freebsd32_misc.c revision 142934
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 142934 2005-03-01 17:45:55Z ps $"); 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> 38123746Speter#include <sys/namei.h> 39100384Speter#include <sys/imgact.h> 40100384Speter#include <sys/kernel.h> 41100384Speter#include <sys/lock.h> 42100384Speter#include <sys/malloc.h> 43100384Speter#include <sys/file.h> /* Must come after sys/malloc.h */ 44100384Speter#include <sys/mman.h> 45100384Speter#include <sys/module.h> 46100384Speter#include <sys/mount.h> 47100384Speter#include <sys/mutex.h> 48100384Speter#include <sys/namei.h> 49100384Speter#include <sys/param.h> 50100384Speter#include <sys/proc.h> 51100384Speter#include <sys/reboot.h> 52100384Speter#include <sys/resource.h> 53100384Speter#include <sys/resourcevar.h> 54100384Speter#include <sys/selinfo.h> 55100384Speter#include <sys/pipe.h> /* Must come after sys/selinfo.h */ 56100384Speter#include <sys/signal.h> 57100384Speter#include <sys/signalvar.h> 58100384Speter#include <sys/socket.h> 59100384Speter#include <sys/socketvar.h> 60100384Speter#include <sys/stat.h> 61113859Sjhb#include <sys/syscallsubr.h> 62100384Speter#include <sys/sysctl.h> 63100384Speter#include <sys/sysent.h> 64100384Speter#include <sys/sysproto.h> 65100384Speter#include <sys/systm.h> 66100384Speter#include <sys/unistd.h> 67100384Speter#include <sys/vnode.h> 68127140Sjhb#include <sys/wait.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 87100384Speterint 88119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) 89100384Speter{ 90127140Sjhb int error, status; 91127140Sjhb struct rusage32 ru32; 92136152Sjhb struct rusage ru, *rup; 93100384Speter 94136152Sjhb if (uap->rusage != NULL) 95136152Sjhb rup = &ru; 96136152Sjhb else 97136152Sjhb rup = NULL; 98136152Sjhb error = kern_wait(td, uap->pid, &status, uap->options, rup); 99100384Speter if (error) 100100384Speter return (error); 101127140Sjhb if (uap->status != NULL) 102127140Sjhb error = copyout(&status, uap->status, sizeof(status)); 103127140Sjhb if (uap->rusage != NULL && error == 0) { 104100384Speter TV_CP(ru, ru32, ru_utime); 105100384Speter TV_CP(ru, ru32, ru_stime); 106100384Speter CP(ru, ru32, ru_maxrss); 107100384Speter CP(ru, ru32, ru_ixrss); 108100384Speter CP(ru, ru32, ru_idrss); 109100384Speter CP(ru, ru32, ru_isrss); 110100384Speter CP(ru, ru32, ru_minflt); 111100384Speter CP(ru, ru32, ru_majflt); 112100384Speter CP(ru, ru32, ru_nswap); 113100384Speter CP(ru, ru32, ru_inblock); 114100384Speter CP(ru, ru32, ru_oublock); 115100384Speter CP(ru, ru32, ru_msgsnd); 116100384Speter CP(ru, ru32, ru_msgrcv); 117100384Speter CP(ru, ru32, ru_nsignals); 118100384Speter CP(ru, ru32, ru_nvcsw); 119100384Speter CP(ru, ru32, ru_nivcsw); 120127140Sjhb error = copyout(&ru32, uap->rusage, sizeof(ru32)); 121100384Speter } 122100384Speter return (error); 123100384Speter} 124100384Speter 125128597Smarcel#ifdef COMPAT_FREEBSD4 126100384Speterstatic void 127100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out) 128100384Speter{ 129100384Speter CP(*in, *out, f_bsize); 130100384Speter CP(*in, *out, f_iosize); 131100384Speter CP(*in, *out, f_blocks); 132100384Speter CP(*in, *out, f_bfree); 133100384Speter CP(*in, *out, f_bavail); 134100384Speter CP(*in, *out, f_files); 135100384Speter CP(*in, *out, f_ffree); 136100384Speter CP(*in, *out, f_fsid); 137100384Speter CP(*in, *out, f_owner); 138100384Speter CP(*in, *out, f_type); 139100384Speter CP(*in, *out, f_flags); 140100384Speter CP(*in, *out, f_flags); 141100384Speter CP(*in, *out, f_syncwrites); 142100384Speter CP(*in, *out, f_asyncwrites); 143100384Speter bcopy(in->f_fstypename, 144100384Speter out->f_fstypename, MFSNAMELEN); 145100384Speter bcopy(in->f_mntonname, 146128260Speter out->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 147100384Speter CP(*in, *out, f_syncreads); 148100384Speter CP(*in, *out, f_asyncreads); 149100384Speter bcopy(in->f_mntfromname, 150128260Speter out->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 151100384Speter} 152128597Smarcel#endif 153100384Speter 154128597Smarcel#ifdef COMPAT_FREEBSD4 155100384Speterint 156128260Speterfreebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap) 157100384Speter{ 158100384Speter int error; 159100384Speter caddr_t sg; 160100384Speter struct statfs32 *sp32, stat32; 161100384Speter struct statfs *sp = NULL, stat; 162100384Speter int maxcount, count, i; 163100384Speter 164107849Salfred sp32 = uap->buf; 165107849Salfred maxcount = uap->bufsize / sizeof(struct statfs32); 166100384Speter 167100384Speter if (sp32) { 168100384Speter sg = stackgap_init(); 169100384Speter sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount); 170107849Salfred uap->buf = (struct statfs32 *)sp; 171100384Speter } 172100384Speter error = getfsstat(td, (struct getfsstat_args *) uap); 173100384Speter if (sp32 && !error) { 174100384Speter count = td->td_retval[0]; 175100384Speter for (i = 0; i < count; i++) { 176100384Speter error = copyin(&sp[i], &stat, sizeof(stat)); 177100384Speter if (error) 178100384Speter return (error); 179100384Speter copy_statfs(&stat, &stat32); 180100384Speter error = copyout(&stat32, &sp32[i], sizeof(stat32)); 181100384Speter if (error) 182100384Speter return (error); 183100384Speter } 184100384Speter } 185100384Speter return (error); 186100384Speter} 187128597Smarcel#endif 188100384Speter 189100384Speterstruct sigaltstack32 { 190100384Speter u_int32_t ss_sp; 191100384Speter u_int32_t ss_size; 192100384Speter int ss_flags; 193100384Speter}; 194100384Speter 195121719SpeterCTASSERT(sizeof(struct sigaltstack32) == 12); 196121719Speter 197100384Speterint 198119333Speterfreebsd32_sigaltstack(struct thread *td, 199119333Speter struct freebsd32_sigaltstack_args *uap) 200100384Speter{ 201113859Sjhb struct sigaltstack32 s32; 202113859Sjhb struct sigaltstack ss, oss, *ssp; 203100384Speter int error; 204100384Speter 205113859Sjhb if (uap->ss != NULL) { 206113859Sjhb error = copyin(uap->ss, &s32, sizeof(s32)); 207100384Speter if (error) 208100384Speter return (error); 209113859Sjhb PTRIN_CP(s32, ss, ss_sp); 210113859Sjhb CP(s32, ss, ss_size); 211113859Sjhb CP(s32, ss, ss_flags); 212113859Sjhb ssp = &ss; 213113859Sjhb } else 214113859Sjhb ssp = NULL; 215113859Sjhb error = kern_sigaltstack(td, ssp, &oss); 216113859Sjhb if (error == 0 && uap->oss != NULL) { 217113859Sjhb PTROUT_CP(oss, s32, ss_sp); 218113859Sjhb CP(oss, s32, ss_size); 219113859Sjhb CP(oss, s32, ss_flags); 220113859Sjhb error = copyout(&s32, uap->oss, sizeof(s32)); 221100384Speter } 222100384Speter return (error); 223100384Speter} 224100384Speter 225142059Sjhb/* 226142059Sjhb * Custom version of exec_copyin_args() so that we can translate 227142059Sjhb * the pointers. 228142059Sjhb */ 229142059Sjhbstatic int 230142059Sjhbfreebsd32_exec_copyin_args(struct image_args *args, char *fname, 231142059Sjhb enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv) 232100384Speter{ 233142059Sjhb char *argp, *envp; 234142059Sjhb u_int32_t *p32, arg; 235142059Sjhb size_t length; 236100384Speter int error; 237100384Speter 238142059Sjhb bzero(args, sizeof(*args)); 239142059Sjhb if (argv == NULL) 240142059Sjhb return (EFAULT); 241100384Speter 242142059Sjhb /* 243142059Sjhb * Allocate temporary demand zeroed space for argument and 244142059Sjhb * environment strings 245142059Sjhb */ 246142059Sjhb args->buf = (char *) kmem_alloc_wait(exec_map, PATH_MAX + ARG_MAX); 247142059Sjhb if (args->buf == NULL) 248142059Sjhb return (ENOMEM); 249142059Sjhb args->begin_argv = args->buf; 250142059Sjhb args->endp = args->begin_argv; 251142059Sjhb args->stringspace = ARG_MAX; 252142059Sjhb 253142059Sjhb args->fname = args->buf + ARG_MAX; 254142059Sjhb 255142059Sjhb /* 256142059Sjhb * Copy the file name. 257142059Sjhb */ 258142059Sjhb error = (segflg == UIO_SYSSPACE) ? 259142059Sjhb copystr(fname, args->fname, PATH_MAX, &length) : 260142059Sjhb copyinstr(fname, args->fname, PATH_MAX, &length); 261142059Sjhb if (error != 0) 262142059Sjhb return (error); 263142059Sjhb 264142059Sjhb /* 265142059Sjhb * extract arguments first 266142059Sjhb */ 267142059Sjhb p32 = argv; 268142059Sjhb for (;;) { 269142059Sjhb error = copyin(p32++, &arg, sizeof(arg)); 270142059Sjhb if (error) 271142059Sjhb return (error); 272142059Sjhb if (arg == 0) 273142059Sjhb break; 274142059Sjhb argp = PTRIN(arg); 275142059Sjhb error = copyinstr(argp, args->endp, args->stringspace, &length); 276142059Sjhb if (error) { 277142059Sjhb if (error == ENAMETOOLONG) 278142059Sjhb return (E2BIG); 279142059Sjhb else 280142059Sjhb return (error); 281142059Sjhb } 282142059Sjhb args->stringspace -= length; 283142059Sjhb args->endp += length; 284142059Sjhb args->argc++; 285100384Speter } 286142059Sjhb 287142059Sjhb args->begin_envv = args->endp; 288142059Sjhb 289142059Sjhb /* 290142059Sjhb * extract environment strings 291142059Sjhb */ 292142059Sjhb if (envv) { 293142059Sjhb p32 = envv; 294142059Sjhb for (;;) { 295100384Speter error = copyin(p32++, &arg, sizeof(arg)); 296100384Speter if (error) 297142059Sjhb return (error); 298142059Sjhb if (arg == 0) 299142059Sjhb break; 300142059Sjhb envp = PTRIN(arg); 301142059Sjhb error = copyinstr(envp, args->endp, args->stringspace, 302142059Sjhb &length); 303142059Sjhb if (error) { 304142059Sjhb if (error == ENAMETOOLONG) 305142059Sjhb return (E2BIG); 306142059Sjhb else 307142059Sjhb return (error); 308142059Sjhb } 309142059Sjhb args->stringspace -= length; 310142059Sjhb args->endp += length; 311142059Sjhb args->envc++; 312142059Sjhb } 313100384Speter } 314100384Speter 315142059Sjhb return (0); 316100384Speter} 317100384Speter 318142059Sjhbint 319142059Sjhbfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) 320142059Sjhb{ 321142059Sjhb struct image_args eargs; 322142059Sjhb int error; 323142059Sjhb 324142059Sjhb error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE, 325142059Sjhb uap->argv, uap->envv); 326142059Sjhb if (error == 0) 327142059Sjhb error = kern_execve(td, &eargs, NULL); 328142059Sjhb exec_free_args(&eargs); 329142059Sjhb return (error); 330142059Sjhb} 331142059Sjhb 332114987Speter#ifdef __ia64__ 333100384Speterstatic int 334119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 335119333Speter int prot, int fd, off_t pos) 336100384Speter{ 337100384Speter vm_map_t map; 338100384Speter vm_map_entry_t entry; 339100384Speter int rv; 340100384Speter 341100384Speter map = &td->td_proc->p_vmspace->vm_map; 342100384Speter if (fd != -1) 343100384Speter prot |= VM_PROT_WRITE; 344100384Speter 345100384Speter if (vm_map_lookup_entry(map, start, &entry)) { 346100384Speter if ((entry->protection & prot) != prot) { 347100384Speter rv = vm_map_protect(map, 348100384Speter trunc_page(start), 349100384Speter round_page(end), 350100384Speter entry->protection | prot, 351100384Speter FALSE); 352100384Speter if (rv != KERN_SUCCESS) 353100384Speter return (EINVAL); 354100384Speter } 355100384Speter } else { 356100384Speter vm_offset_t addr = trunc_page(start); 357100384Speter rv = vm_map_find(map, 0, 0, 358100384Speter &addr, PAGE_SIZE, FALSE, prot, 359100384Speter VM_PROT_ALL, 0); 360100384Speter if (rv != KERN_SUCCESS) 361100384Speter return (EINVAL); 362100384Speter } 363100384Speter 364100384Speter if (fd != -1) { 365100384Speter struct pread_args r; 366107849Salfred r.fd = fd; 367107849Salfred r.buf = (void *) start; 368107849Salfred r.nbyte = end - start; 369107849Salfred r.offset = pos; 370100384Speter return (pread(td, &r)); 371100384Speter } else { 372100384Speter while (start < end) { 373100384Speter subyte((void *) start, 0); 374100384Speter start++; 375100384Speter } 376100384Speter return (0); 377100384Speter } 378100384Speter} 379114987Speter#endif 380100384Speter 381100384Speterint 382119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) 383100384Speter{ 384100384Speter struct mmap_args ap; 385107849Salfred vm_offset_t addr = (vm_offset_t) uap->addr; 386107849Salfred vm_size_t len = uap->len; 387107849Salfred int prot = uap->prot; 388107849Salfred int flags = uap->flags; 389107849Salfred int fd = uap->fd; 390107849Salfred off_t pos = (uap->poslo 391107849Salfred | ((off_t)uap->poshi << 32)); 392114987Speter#ifdef __ia64__ 393100384Speter vm_size_t pageoff; 394100384Speter int error; 395100384Speter 396100384Speter /* 397100384Speter * Attempt to handle page size hassles. 398100384Speter */ 399100384Speter pageoff = (pos & PAGE_MASK); 400100384Speter if (flags & MAP_FIXED) { 401100384Speter vm_offset_t start, end; 402100384Speter start = addr; 403100384Speter end = addr + len; 404100384Speter 405100384Speter if (start != trunc_page(start)) { 406119333Speter error = freebsd32_mmap_partial(td, start, 407119333Speter round_page(start), prot, 408119333Speter fd, pos); 409100384Speter if (fd != -1) 410100384Speter pos += round_page(start) - start; 411100384Speter start = round_page(start); 412100384Speter } 413100384Speter if (end != round_page(end)) { 414100384Speter vm_offset_t t = trunc_page(end); 415119333Speter error = freebsd32_mmap_partial(td, t, end, 416100384Speter prot, fd, 417100384Speter pos + t - start); 418100384Speter end = trunc_page(end); 419100384Speter } 420100384Speter if (end > start && fd != -1 && (pos & PAGE_MASK)) { 421100384Speter /* 422100384Speter * We can't map this region at all. The specified 423100384Speter * address doesn't have the same alignment as the file 424100384Speter * position. Fake the mapping by simply reading the 425100384Speter * entire region into memory. First we need to make 426100384Speter * sure the region exists. 427100384Speter */ 428100384Speter vm_map_t map; 429100384Speter struct pread_args r; 430100384Speter int rv; 431100384Speter 432100384Speter prot |= VM_PROT_WRITE; 433100384Speter map = &td->td_proc->p_vmspace->vm_map; 434100384Speter rv = vm_map_remove(map, start, end); 435100384Speter if (rv != KERN_SUCCESS) 436100384Speter return (EINVAL); 437100384Speter rv = vm_map_find(map, 0, 0, 438100384Speter &start, end - start, FALSE, 439100384Speter prot, VM_PROT_ALL, 0); 440100384Speter if (rv != KERN_SUCCESS) 441100384Speter return (EINVAL); 442107849Salfred r.fd = fd; 443107849Salfred r.buf = (void *) start; 444107849Salfred r.nbyte = end - start; 445107849Salfred r.offset = pos; 446100384Speter error = pread(td, &r); 447100384Speter if (error) 448100384Speter return (error); 449100384Speter 450100384Speter td->td_retval[0] = addr; 451100384Speter return (0); 452100384Speter } 453100384Speter if (end == start) { 454100384Speter /* 455100384Speter * After dealing with the ragged ends, there 456100384Speter * might be none left. 457100384Speter */ 458100384Speter td->td_retval[0] = addr; 459100384Speter return (0); 460100384Speter } 461100384Speter addr = start; 462100384Speter len = end - start; 463100384Speter } 464114987Speter#endif 465100384Speter 466107849Salfred ap.addr = (void *) addr; 467107849Salfred ap.len = len; 468107849Salfred ap.prot = prot; 469107849Salfred ap.flags = flags; 470107849Salfred ap.fd = fd; 471107849Salfred ap.pos = pos; 472100384Speter 473100384Speter return (mmap(td, &ap)); 474100384Speter} 475100384Speter 476100384Speterstruct itimerval32 { 477100384Speter struct timeval32 it_interval; 478100384Speter struct timeval32 it_value; 479100384Speter}; 480100384Speter 481121719SpeterCTASSERT(sizeof(struct itimerval32) == 16); 482121719Speter 483100384Speterint 484119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) 485100384Speter{ 486142059Sjhb struct itimerval itv, oitv, *itvp; 487142059Sjhb struct itimerval32 i32; 488100384Speter int error; 489100384Speter 490142059Sjhb if (uap->itv != NULL) { 491142059Sjhb error = copyin(uap->itv, &i32, sizeof(i32)); 492100384Speter if (error) 493100384Speter return (error); 494142059Sjhb TV_CP(i32, itv, it_interval); 495142059Sjhb TV_CP(i32, itv, it_value); 496142059Sjhb itvp = &itv; 497142059Sjhb } else 498142059Sjhb itvp = NULL; 499142059Sjhb error = kern_setitimer(td, uap->which, itvp, &oitv); 500142059Sjhb if (error || uap->oitv == NULL) 501100384Speter return (error); 502142059Sjhb TV_CP(oitv, i32, it_interval); 503142059Sjhb TV_CP(oitv, i32, it_value); 504142059Sjhb return (copyout(&i32, uap->oitv, sizeof(i32))); 505100384Speter} 506100384Speter 507100384Speterint 508125171Speterfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap) 509125171Speter{ 510142059Sjhb struct itimerval itv; 511142059Sjhb struct itimerval32 i32; 512125171Speter int error; 513125171Speter 514142059Sjhb error = kern_getitimer(td, uap->which, &itv); 515142059Sjhb if (error || uap->itv == NULL) 516125171Speter return (error); 517142059Sjhb TV_CP(itv, i32, it_interval); 518142059Sjhb TV_CP(itv, i32, it_value); 519142059Sjhb return (copyout(&i32, uap->itv, sizeof(i32))); 520125171Speter} 521125171Speter 522125171Speterint 523119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap) 524100384Speter{ 525142059Sjhb struct timeval32 tv32; 526142059Sjhb struct timeval tv, *tvp; 527100384Speter int error; 528100384Speter 529142059Sjhb if (uap->tv != NULL) { 530142059Sjhb error = copyin(uap->tv, &tv32, sizeof(tv32)); 531100384Speter if (error) 532100384Speter return (error); 533142059Sjhb CP(tv32, tv, tv_sec); 534142059Sjhb CP(tv32, tv, tv_usec); 535142059Sjhb tvp = &tv; 536142059Sjhb } else 537142059Sjhb tvp = NULL; 538100384Speter /* 539100384Speter * XXX big-endian needs to convert the fd_sets too. 540142059Sjhb * XXX Do pointers need PTRIN()? 541100384Speter */ 542142059Sjhb return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp)); 543100384Speter} 544100384Speter 545114987Speterstruct kevent32 { 546114987Speter u_int32_t ident; /* identifier for this event */ 547114987Speter short filter; /* filter for event */ 548114987Speter u_short flags; 549114987Speter u_int fflags; 550114987Speter int32_t data; 551114987Speter u_int32_t udata; /* opaque user data identifier */ 552114987Speter}; 553114987Speter 554121719SpeterCTASSERT(sizeof(struct kevent32) == 20); 555121719Speter 556100384Speterint 557119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) 558114987Speter{ 559114987Speter struct timespec32 ts32; 560142934Sps struct timespec ts, *tsp; 561142934Sps struct kevent *ks; 562114987Speter struct kevent32 ks32; 563142934Sps struct kevent *changes, *events; 564142934Sps int error, i; 565114987Speter 566114987Speter 567114987Speter if (uap->timeout) { 568114987Speter error = copyin(uap->timeout, &ts32, sizeof(ts32)); 569114987Speter if (error) 570114987Speter return (error); 571114987Speter CP(ts32, ts, tv_sec); 572114987Speter CP(ts32, ts, tv_nsec); 573142934Sps tsp = &ts; 574142934Sps } else 575142934Sps tsp = NULL; 576142934Sps if (uap->changelist && uap->nchanges > 0) { 577142934Sps changes = malloc(sizeof(struct kevent) * uap->nchanges, M_TEMP, 578142934Sps M_WAITOK); 579114987Speter for (i = 0; i < uap->nchanges; i++) { 580119333Speter error = copyin(&uap->changelist[i], &ks32, 581119333Speter sizeof(ks32)); 582142934Sps if (error) { 583142934Sps free(changes, M_TEMP); 584114987Speter return (error); 585142934Sps } 586142934Sps ks = &changes[i]; 587114987Speter CP(ks32, *ks, ident); 588114987Speter CP(ks32, *ks, filter); 589114987Speter CP(ks32, *ks, flags); 590114987Speter CP(ks32, *ks, fflags); 591114987Speter CP(ks32, *ks, data); 592114987Speter PTRIN_CP(ks32, *ks, udata); 593114987Speter } 594142934Sps } else 595142934Sps changes = NULL; 596142934Sps if (uap->eventlist && uap->nevents > 0) 597142934Sps events = malloc(sizeof(struct kevent) * uap->nevents, M_TEMP, 598142934Sps M_WAITOK); 599142934Sps else 600142934Sps events = NULL; 601142934Sps error = kern_kevent(td, uap->fd, changes, uap->nchanges, UIO_SYSSPACE, 602142934Sps events, uap->nevents, UIO_SYSSPACE, tsp); 603142934Sps free(changes, M_TEMP); 604142934Sps if (uap->eventlist && events && td->td_retval[0] > 0) { 605142934Sps for (i = 0; i < td->td_retval[0]; i++) { 606142934Sps ks = &events[i]; 607114987Speter CP(*ks, ks32, ident); 608114987Speter CP(*ks, ks32, filter); 609114987Speter CP(*ks, ks32, flags); 610114987Speter CP(*ks, ks32, fflags); 611114987Speter CP(*ks, ks32, data); 612114987Speter PTROUT_CP(*ks, ks32, udata); 613119333Speter error = copyout(&ks32, &uap->eventlist[i], 614119333Speter sizeof(ks32)); 615114987Speter if (error) 616142934Sps break; 617114987Speter } 618114987Speter } 619142934Sps if (events) 620142934Sps free(events, M_TEMP); 621142934Sps return (error); 622114987Speter} 623114987Speter 624114987Speterint 625119333Speterfreebsd32_gettimeofday(struct thread *td, 626119333Speter struct freebsd32_gettimeofday_args *uap) 627100384Speter{ 628123425Speter struct timeval atv; 629123425Speter struct timeval32 atv32; 630123425Speter struct timezone rtz; 631123425Speter int error = 0; 632100384Speter 633123425Speter if (uap->tp) { 634123425Speter microtime(&atv); 635123425Speter CP(atv, atv32, tv_sec); 636123425Speter CP(atv, atv32, tv_usec); 637123425Speter error = copyout(&atv32, uap->tp, sizeof (atv32)); 638100384Speter } 639123425Speter if (error == 0 && uap->tzp != NULL) { 640123425Speter rtz.tz_minuteswest = tz_minuteswest; 641123425Speter rtz.tz_dsttime = tz_dsttime; 642123425Speter error = copyout(&rtz, uap->tzp, sizeof (rtz)); 643100384Speter } 644100384Speter return (error); 645100384Speter} 646100384Speter 647100384Speterint 648119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) 649100384Speter{ 650136152Sjhb struct rusage32 s32; 651136152Sjhb struct rusage s; 652100384Speter int error; 653100384Speter 654136152Sjhb error = kern_getrusage(td, uap->who, &s); 655100384Speter if (error) 656100384Speter return (error); 657136152Sjhb if (uap->rusage != NULL) { 658100384Speter TV_CP(s, s32, ru_utime); 659100384Speter TV_CP(s, s32, ru_stime); 660100384Speter CP(s, s32, ru_maxrss); 661100384Speter CP(s, s32, ru_ixrss); 662100384Speter CP(s, s32, ru_idrss); 663100384Speter CP(s, s32, ru_isrss); 664100384Speter CP(s, s32, ru_minflt); 665100384Speter CP(s, s32, ru_majflt); 666100384Speter CP(s, s32, ru_nswap); 667100384Speter CP(s, s32, ru_inblock); 668100384Speter CP(s, s32, ru_oublock); 669100384Speter CP(s, s32, ru_msgsnd); 670100384Speter CP(s, s32, ru_msgrcv); 671100384Speter CP(s, s32, ru_nsignals); 672100384Speter CP(s, s32, ru_nvcsw); 673100384Speter CP(s, s32, ru_nivcsw); 674136152Sjhb error = copyout(&s32, uap->rusage, sizeof(s32)); 675100384Speter } 676100384Speter return (error); 677100384Speter} 678100384Speter 679100384Speterstruct iovec32 { 680100384Speter u_int32_t iov_base; 681100384Speter int iov_len; 682100384Speter}; 683100384Speter#define STACKGAPLEN 400 684100384Speter 685121719SpeterCTASSERT(sizeof(struct iovec32) == 8); 686121719Speter 687100384Speterint 688119333Speterfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) 689100384Speter{ 690100384Speter int error, osize, nsize, i; 691100384Speter caddr_t sg; 692100384Speter struct readv_args /* { 693100384Speter syscallarg(int) fd; 694100384Speter syscallarg(struct iovec *) iovp; 695100384Speter syscallarg(u_int) iovcnt; 696100384Speter } */ a; 697100384Speter struct iovec32 *oio; 698100384Speter struct iovec *nio; 699100384Speter 700100384Speter sg = stackgap_init(); 701100384Speter 702107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 703100384Speter return (EINVAL); 704100384Speter 705107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 706107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 707100384Speter 708111119Simp oio = malloc(osize, M_TEMP, M_WAITOK); 709111119Simp nio = malloc(nsize, M_TEMP, M_WAITOK); 710100384Speter 711100384Speter error = 0; 712107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 713100384Speter goto punt; 714107849Salfred for (i = 0; i < uap->iovcnt; i++) { 715100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 716100384Speter nio[i].iov_len = oio[i].iov_len; 717100384Speter } 718100384Speter 719107849Salfred a.fd = uap->fd; 720107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 721107849Salfred a.iovcnt = uap->iovcnt; 722100384Speter 723107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 724100384Speter goto punt; 725100384Speter error = readv(td, &a); 726100384Speter 727100384Speterpunt: 728100384Speter free(oio, M_TEMP); 729100384Speter free(nio, M_TEMP); 730100384Speter return (error); 731100384Speter} 732100384Speter 733100384Speterint 734119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) 735100384Speter{ 736100384Speter int error, i, nsize, osize; 737100384Speter caddr_t sg; 738100384Speter struct writev_args /* { 739100384Speter syscallarg(int) fd; 740100384Speter syscallarg(struct iovec *) iovp; 741100384Speter syscallarg(u_int) iovcnt; 742100384Speter } */ a; 743100384Speter struct iovec32 *oio; 744100384Speter struct iovec *nio; 745100384Speter 746100384Speter sg = stackgap_init(); 747100384Speter 748107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 749100384Speter return (EINVAL); 750100384Speter 751107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 752107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 753100384Speter 754111119Simp oio = malloc(osize, M_TEMP, M_WAITOK); 755111119Simp nio = malloc(nsize, M_TEMP, M_WAITOK); 756100384Speter 757100384Speter error = 0; 758107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 759100384Speter goto punt; 760107849Salfred for (i = 0; i < uap->iovcnt; i++) { 761100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 762100384Speter nio[i].iov_len = oio[i].iov_len; 763100384Speter } 764100384Speter 765107849Salfred a.fd = uap->fd; 766107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 767107849Salfred a.iovcnt = uap->iovcnt; 768100384Speter 769107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 770100384Speter goto punt; 771100384Speter error = writev(td, &a); 772100384Speter 773100384Speterpunt: 774100384Speter free(oio, M_TEMP); 775100384Speter free(nio, M_TEMP); 776100384Speter return (error); 777100384Speter} 778100384Speter 779100384Speterint 780119333Speterfreebsd32_settimeofday(struct thread *td, 781119333Speter struct freebsd32_settimeofday_args *uap) 782100384Speter{ 783100384Speter int error; 784100384Speter caddr_t sg; 785100384Speter struct timeval32 *p32, s32; 786100384Speter struct timeval *p = NULL, s; 787100384Speter 788107849Salfred p32 = uap->tv; 789100384Speter if (p32) { 790100384Speter sg = stackgap_init(); 791100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 792107849Salfred uap->tv = (struct timeval32 *)p; 793100384Speter error = copyin(p32, &s32, sizeof(s32)); 794100384Speter if (error) 795100384Speter return (error); 796100384Speter CP(s32, s, tv_sec); 797100384Speter CP(s32, s, tv_usec); 798100384Speter error = copyout(&s, p, sizeof(s)); 799100384Speter if (error) 800100384Speter return (error); 801100384Speter } 802100384Speter return (settimeofday(td, (struct settimeofday_args *) uap)); 803100384Speter} 804100384Speter 805100384Speterint 806119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) 807100384Speter{ 808142059Sjhb struct timeval32 s32[2]; 809142059Sjhb struct timeval s[2], *sp; 810100384Speter int error; 811100384Speter 812142059Sjhb if (uap->tptr != NULL) { 813142059Sjhb error = copyin(uap->tptr, s32, sizeof(s32)); 814100384Speter if (error) 815100384Speter return (error); 816100384Speter CP(s32[0], s[0], tv_sec); 817100384Speter CP(s32[0], s[0], tv_usec); 818100384Speter CP(s32[1], s[1], tv_sec); 819100384Speter CP(s32[1], s[1], tv_usec); 820142059Sjhb sp = s; 821142059Sjhb } else 822142059Sjhb sp = NULL; 823142059Sjhb return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE)); 824100384Speter} 825100384Speter 826100384Speterint 827119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) 828100384Speter{ 829100384Speter int error; 830100384Speter caddr_t sg; 831100384Speter struct timeval32 *p32, *op32, s32; 832100384Speter struct timeval *p = NULL, *op = NULL, s; 833100384Speter 834107849Salfred p32 = uap->delta; 835100384Speter if (p32) { 836100384Speter sg = stackgap_init(); 837100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 838107849Salfred uap->delta = (struct timeval32 *)p; 839100384Speter error = copyin(p32, &s32, sizeof(s32)); 840100384Speter if (error) 841100384Speter return (error); 842100384Speter CP(s32, s, tv_sec); 843100384Speter CP(s32, s, tv_usec); 844100384Speter error = copyout(&s, p, sizeof(s)); 845100384Speter if (error) 846100384Speter return (error); 847100384Speter } 848107849Salfred op32 = uap->olddelta; 849100384Speter if (op32) { 850100384Speter sg = stackgap_init(); 851100384Speter op = stackgap_alloc(&sg, sizeof(struct timeval)); 852107849Salfred uap->olddelta = (struct timeval32 *)op; 853100384Speter } 854142059Sjhb error = adjtime(td, (struct adjtime_args *) uap); 855100384Speter if (error) 856100384Speter return error; 857100384Speter if (op32) { 858100384Speter error = copyin(op, &s, sizeof(s)); 859100384Speter if (error) 860100384Speter return (error); 861100384Speter CP(s, s32, tv_sec); 862100384Speter CP(s, s32, tv_usec); 863100384Speter error = copyout(&s32, op32, sizeof(s32)); 864100384Speter } 865100384Speter return (error); 866100384Speter} 867100384Speter 868128597Smarcel#ifdef COMPAT_FREEBSD4 869100384Speterint 870128260Speterfreebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap) 871100384Speter{ 872142059Sjhb struct statfs32 s32; 873142059Sjhb struct statfs s; 874100384Speter int error; 875100384Speter 876142059Sjhb error = kern_statfs(td, uap->path, UIO_USERSPACE, &s); 877100384Speter if (error) 878100384Speter return (error); 879142059Sjhb copy_statfs(&s, &s32); 880142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 881100384Speter} 882128597Smarcel#endif 883100384Speter 884128597Smarcel#ifdef COMPAT_FREEBSD4 885100384Speterint 886128260Speterfreebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap) 887100384Speter{ 888142059Sjhb struct statfs32 s32; 889142059Sjhb struct statfs s; 890100384Speter int error; 891100384Speter 892142059Sjhb error = kern_fstatfs(td, uap->fd, &s); 893100384Speter if (error) 894100384Speter return (error); 895142059Sjhb copy_statfs(&s, &s32); 896142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 897100384Speter} 898128597Smarcel#endif 899100384Speter 900128597Smarcel#ifdef COMPAT_FREEBSD4 901100384Speterint 902128260Speterfreebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap) 903128260Speter{ 904142059Sjhb struct statfs32 s32; 905142059Sjhb struct statfs s; 906142059Sjhb fhandle_t fh; 907128260Speter int error; 908128260Speter 909142059Sjhb if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) 910142059Sjhb return (error); 911142059Sjhb error = kern_fhstatfs(td, fh, &s); 912128260Speter if (error) 913128260Speter return (error); 914142059Sjhb copy_statfs(&s, &s32); 915142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 916128260Speter} 917128597Smarcel#endif 918128260Speter 919128260Speterint 920119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) 921100384Speter{ 922100384Speter /* 923100384Speter * Vector through to semsys if it is loaded. 924100384Speter */ 925100384Speter return sysent[169].sy_call(td, uap); 926100384Speter} 927100384Speter 928100384Speterint 929119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap) 930100384Speter{ 931100384Speter /* 932100384Speter * Vector through to msgsys if it is loaded. 933100384Speter */ 934100384Speter return sysent[170].sy_call(td, uap); 935100384Speter} 936100384Speter 937100384Speterint 938119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap) 939100384Speter{ 940100384Speter /* 941100384Speter * Vector through to shmsys if it is loaded. 942100384Speter */ 943100384Speter return sysent[171].sy_call(td, uap); 944100384Speter} 945100384Speter 946100384Speterint 947119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) 948100384Speter{ 949100384Speter struct pread_args ap; 950100384Speter 951107849Salfred ap.fd = uap->fd; 952107849Salfred ap.buf = uap->buf; 953107849Salfred ap.nbyte = uap->nbyte; 954119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 955100384Speter return (pread(td, &ap)); 956100384Speter} 957100384Speter 958100384Speterint 959119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) 960100384Speter{ 961100384Speter struct pwrite_args ap; 962100384Speter 963107849Salfred ap.fd = uap->fd; 964107849Salfred ap.buf = uap->buf; 965107849Salfred ap.nbyte = uap->nbyte; 966119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 967100384Speter return (pwrite(td, &ap)); 968100384Speter} 969100384Speter 970100384Speterint 971119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) 972100384Speter{ 973100384Speter int error; 974100384Speter struct lseek_args ap; 975100384Speter off_t pos; 976100384Speter 977107849Salfred ap.fd = uap->fd; 978119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 979107849Salfred ap.whence = uap->whence; 980100384Speter error = lseek(td, &ap); 981100384Speter /* Expand the quad return into two parts for eax and edx */ 982100384Speter pos = *(off_t *)(td->td_retval); 983100384Speter td->td_retval[0] = pos & 0xffffffff; /* %eax */ 984100384Speter td->td_retval[1] = pos >> 32; /* %edx */ 985100384Speter return error; 986100384Speter} 987100384Speter 988100384Speterint 989119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) 990100384Speter{ 991100384Speter struct truncate_args ap; 992100384Speter 993107849Salfred ap.path = uap->path; 994119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 995100384Speter return (truncate(td, &ap)); 996100384Speter} 997100384Speter 998100384Speterint 999119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 1000100384Speter{ 1001100384Speter struct ftruncate_args ap; 1002100384Speter 1003107849Salfred ap.fd = uap->fd; 1004119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1005100384Speter return (ftruncate(td, &ap)); 1006100384Speter} 1007100384Speter 1008104738Speter#ifdef COMPAT_FREEBSD4 1009100384Speterint 1010119333Speterfreebsd4_freebsd32_sendfile(struct thread *td, 1011119333Speter struct freebsd4_freebsd32_sendfile_args *uap) 1012104738Speter{ 1013104738Speter struct freebsd4_sendfile_args ap; 1014104738Speter 1015107849Salfred ap.fd = uap->fd; 1016107849Salfred ap.s = uap->s; 1017119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1018107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1019107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1020107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1021107849Salfred ap.flags = uap->flags; 1022104738Speter return (freebsd4_sendfile(td, &ap)); 1023104738Speter} 1024104738Speter#endif 1025104738Speter 1026104738Speterint 1027119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) 1028100384Speter{ 1029100384Speter struct sendfile_args ap; 1030100384Speter 1031107849Salfred ap.fd = uap->fd; 1032107849Salfred ap.s = uap->s; 1033119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1034107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1035107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1036107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1037107849Salfred ap.flags = uap->flags; 1038100384Speter return (sendfile(td, &ap)); 1039100384Speter} 1040100384Speter 1041100384Speterstruct stat32 { 1042130640Sphk dev_t st_dev; 1043100384Speter ino_t st_ino; 1044100384Speter mode_t st_mode; 1045100384Speter nlink_t st_nlink; 1046100384Speter uid_t st_uid; 1047100384Speter gid_t st_gid; 1048130640Sphk dev_t st_rdev; 1049100384Speter struct timespec32 st_atimespec; 1050100384Speter struct timespec32 st_mtimespec; 1051100384Speter struct timespec32 st_ctimespec; 1052100384Speter off_t st_size; 1053100384Speter int64_t st_blocks; 1054100384Speter u_int32_t st_blksize; 1055100384Speter u_int32_t st_flags; 1056100384Speter u_int32_t st_gen; 1057121719Speter struct timespec32 st_birthtimespec; 1058121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1059121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1060100384Speter}; 1061100384Speter 1062121719Speter 1063121719SpeterCTASSERT(sizeof(struct stat32) == 96); 1064121719Speter 1065100384Speterstatic void 1066100384Spetercopy_stat( struct stat *in, struct stat32 *out) 1067100384Speter{ 1068100384Speter CP(*in, *out, st_dev); 1069100384Speter CP(*in, *out, st_ino); 1070100384Speter CP(*in, *out, st_mode); 1071100384Speter CP(*in, *out, st_nlink); 1072100384Speter CP(*in, *out, st_uid); 1073100384Speter CP(*in, *out, st_gid); 1074100384Speter CP(*in, *out, st_rdev); 1075100384Speter TS_CP(*in, *out, st_atimespec); 1076100384Speter TS_CP(*in, *out, st_mtimespec); 1077100384Speter TS_CP(*in, *out, st_ctimespec); 1078100384Speter CP(*in, *out, st_size); 1079100384Speter CP(*in, *out, st_blocks); 1080100384Speter CP(*in, *out, st_blksize); 1081100384Speter CP(*in, *out, st_flags); 1082100384Speter CP(*in, *out, st_gen); 1083100384Speter} 1084100384Speter 1085100384Speterint 1086119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) 1087100384Speter{ 1088123746Speter struct stat sb; 1089123746Speter struct stat32 sb32; 1090100384Speter int error; 1091100384Speter 1092142059Sjhb error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 1093100384Speter if (error) 1094100384Speter return (error); 1095123746Speter copy_stat(&sb, &sb32); 1096123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1097100384Speter return (error); 1098100384Speter} 1099100384Speter 1100100384Speterint 1101119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) 1102100384Speter{ 1103123746Speter struct stat ub; 1104123746Speter struct stat32 ub32; 1105100384Speter int error; 1106100384Speter 1107142059Sjhb error = kern_fstat(td, uap->fd, &ub); 1108100384Speter if (error) 1109100384Speter return (error); 1110123746Speter copy_stat(&ub, &ub32); 1111123746Speter error = copyout(&ub32, uap->ub, sizeof(ub32)); 1112100384Speter return (error); 1113100384Speter} 1114100384Speter 1115100384Speterint 1116119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) 1117100384Speter{ 1118123746Speter struct stat sb; 1119123746Speter struct stat32 sb32; 1120142059Sjhb int error; 1121100384Speter 1122142059Sjhb error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 1123100384Speter if (error) 1124100384Speter return (error); 1125123746Speter copy_stat(&sb, &sb32); 1126123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1127100384Speter return (error); 1128100384Speter} 1129100384Speter 1130100384Speter/* 1131100384Speter * MPSAFE 1132100384Speter */ 1133100384Speterint 1134119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) 1135100384Speter{ 1136100384Speter int error, name[CTL_MAXNAME]; 1137100384Speter size_t j, oldlen; 1138100384Speter 1139100384Speter if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1140100384Speter return (EINVAL); 1141136404Speter error = copyin(uap->name, name, uap->namelen * sizeof(int)); 1142100384Speter if (error) 1143100384Speter return (error); 1144100384Speter mtx_lock(&Giant); 1145100384Speter if (uap->oldlenp) 1146100384Speter oldlen = fuword32(uap->oldlenp); 1147100384Speter else 1148100384Speter oldlen = 0; 1149100384Speter error = userland_sysctl(td, name, uap->namelen, 1150100384Speter uap->old, &oldlen, 1, 1151136404Speter uap->new, uap->newlen, &j, SCTL_MASK32); 1152100384Speter if (error && error != ENOMEM) 1153100384Speter goto done2; 1154136404Speter if (uap->oldlenp) 1155100384Speter suword32(uap->oldlenp, j); 1156100384Speterdone2: 1157100384Speter mtx_unlock(&Giant); 1158100384Speter return (error); 1159100384Speter} 1160100384Speter 1161100384Speterstruct sigaction32 { 1162100384Speter u_int32_t sa_u; 1163100384Speter int sa_flags; 1164100384Speter sigset_t sa_mask; 1165100384Speter}; 1166100384Speter 1167121719SpeterCTASSERT(sizeof(struct sigaction32) == 24); 1168121719Speter 1169100384Speterint 1170119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) 1171100384Speter{ 1172113859Sjhb struct sigaction32 s32; 1173113859Sjhb struct sigaction sa, osa, *sap; 1174100384Speter int error; 1175100384Speter 1176113859Sjhb if (uap->act) { 1177113859Sjhb error = copyin(uap->act, &s32, sizeof(s32)); 1178100384Speter if (error) 1179100384Speter return (error); 1180113859Sjhb sa.sa_handler = PTRIN(s32.sa_u); 1181113859Sjhb CP(s32, sa, sa_flags); 1182113859Sjhb CP(s32, sa, sa_mask); 1183113859Sjhb sap = &sa; 1184113859Sjhb } else 1185113859Sjhb sap = NULL; 1186113859Sjhb error = kern_sigaction(td, uap->sig, sap, &osa, 0); 1187113859Sjhb if (error != 0 && uap->oact != NULL) { 1188113859Sjhb s32.sa_u = PTROUT(osa.sa_handler); 1189113859Sjhb CP(osa, s32, sa_flags); 1190113859Sjhb CP(osa, s32, sa_mask); 1191113859Sjhb error = copyout(&s32, uap->oact, sizeof(s32)); 1192100384Speter } 1193100384Speter return (error); 1194100384Speter} 1195100384Speter 1196114987Speter#ifdef COMPAT_FREEBSD4 1197114987Speterint 1198119333Speterfreebsd4_freebsd32_sigaction(struct thread *td, 1199119333Speter struct freebsd4_freebsd32_sigaction_args *uap) 1200114987Speter{ 1201114987Speter struct sigaction32 s32; 1202114987Speter struct sigaction sa, osa, *sap; 1203114987Speter int error; 1204114987Speter 1205114987Speter if (uap->act) { 1206114987Speter error = copyin(uap->act, &s32, sizeof(s32)); 1207114987Speter if (error) 1208114987Speter return (error); 1209114987Speter sa.sa_handler = PTRIN(s32.sa_u); 1210114987Speter CP(s32, sa, sa_flags); 1211114987Speter CP(s32, sa, sa_mask); 1212114987Speter sap = &sa; 1213114987Speter } else 1214114987Speter sap = NULL; 1215114987Speter error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 1216114987Speter if (error != 0 && uap->oact != NULL) { 1217114987Speter s32.sa_u = PTROUT(osa.sa_handler); 1218114987Speter CP(osa, s32, sa_flags); 1219114987Speter CP(osa, s32, sa_mask); 1220114987Speter error = copyout(&s32, uap->oact, sizeof(s32)); 1221114987Speter } 1222114987Speter return (error); 1223114987Speter} 1224114987Speter#endif 1225114987Speter 1226140481Spsint 1227140481Spsfreebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap) 1228140481Sps{ 1229140481Sps struct timespec32 rmt32, rqt32; 1230140481Sps struct timespec rmt, rqt; 1231140481Sps int error; 1232140481Sps 1233140481Sps error = copyin(uap->rqtp, &rqt32, sizeof(rqt)); 1234140481Sps if (error) 1235140481Sps return (error); 1236140481Sps 1237140481Sps CP(rqt32, rqt, tv_sec); 1238140481Sps CP(rqt32, rqt, tv_nsec); 1239140481Sps 1240140481Sps if (uap->rmtp && 1241140481Sps !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) 1242140481Sps return (EFAULT); 1243140481Sps error = kern_nanosleep(td, &rqt, &rmt); 1244140481Sps if (error && uap->rmtp) { 1245140481Sps int error2; 1246140481Sps 1247140481Sps CP(rmt, rmt32, tv_sec); 1248140481Sps CP(rmt, rmt32, tv_nsec); 1249140481Sps 1250140481Sps error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt)); 1251140481Sps if (error2) 1252140481Sps error = error2; 1253140481Sps } 1254140481Sps return (error); 1255140481Sps} 1256140481Sps 1257100384Speter#if 0 1258100384Speter 1259100384Speterint 1260119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) 1261100384Speter{ 1262100384Speter int error; 1263100384Speter caddr_t sg; 1264100384Speter struct yyy32 *p32, s32; 1265100384Speter struct yyy *p = NULL, s; 1266100384Speter 1267107849Salfred p32 = uap->zzz; 1268100384Speter if (p32) { 1269100384Speter sg = stackgap_init(); 1270100384Speter p = stackgap_alloc(&sg, sizeof(struct yyy)); 1271107849Salfred uap->zzz = (struct yyy32 *)p; 1272100384Speter error = copyin(p32, &s32, sizeof(s32)); 1273100384Speter if (error) 1274100384Speter return (error); 1275100384Speter /* translate in */ 1276100384Speter error = copyout(&s, p, sizeof(s)); 1277100384Speter if (error) 1278100384Speter return (error); 1279100384Speter } 1280100384Speter error = xxx(td, (struct xxx_args *) uap); 1281100384Speter if (error) 1282100384Speter return (error); 1283100384Speter if (p32) { 1284100384Speter error = copyin(p, &s, sizeof(s)); 1285100384Speter if (error) 1286100384Speter return (error); 1287100384Speter /* translate out */ 1288100384Speter error = copyout(&s32, p32, sizeof(s32)); 1289100384Speter } 1290100384Speter return (error); 1291100384Speter} 1292100384Speter 1293100384Speter#endif 1294