freebsd32_misc.c revision 136152
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 136152 2004-10-05 18:51:11Z jhb $"); 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/user.h> 68100384Speter#include <sys/utsname.h> 69100384Speter#include <sys/vnode.h> 70127140Sjhb#include <sys/wait.h> 71100384Speter 72100384Speter#include <vm/vm.h> 73100384Speter#include <vm/vm_kern.h> 74100384Speter#include <vm/vm_param.h> 75100384Speter#include <vm/pmap.h> 76100384Speter#include <vm/vm_map.h> 77100384Speter#include <vm/vm_object.h> 78100384Speter#include <vm/vm_extern.h> 79100384Speter 80119333Speter#include <compat/freebsd32/freebsd32_util.h> 81119333Speter#include <compat/freebsd32/freebsd32.h> 82119333Speter#include <compat/freebsd32/freebsd32_proto.h> 83100384Speter 84121719SpeterCTASSERT(sizeof(struct timeval32) == 8); 85121719SpeterCTASSERT(sizeof(struct timespec32) == 8); 86121719SpeterCTASSERT(sizeof(struct statfs32) == 256); 87121719SpeterCTASSERT(sizeof(struct rusage32) == 72); 88121719Speter 89100384Speterint 90119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) 91100384Speter{ 92127140Sjhb int error, status; 93127140Sjhb struct rusage32 ru32; 94136152Sjhb struct rusage ru, *rup; 95100384Speter 96136152Sjhb if (uap->rusage != NULL) 97136152Sjhb rup = &ru; 98136152Sjhb else 99136152Sjhb rup = NULL; 100136152Sjhb error = kern_wait(td, uap->pid, &status, uap->options, rup); 101100384Speter if (error) 102100384Speter return (error); 103127140Sjhb if (uap->status != NULL) 104127140Sjhb error = copyout(&status, uap->status, sizeof(status)); 105127140Sjhb if (uap->rusage != NULL && error == 0) { 106100384Speter TV_CP(ru, ru32, ru_utime); 107100384Speter TV_CP(ru, ru32, ru_stime); 108100384Speter CP(ru, ru32, ru_maxrss); 109100384Speter CP(ru, ru32, ru_ixrss); 110100384Speter CP(ru, ru32, ru_idrss); 111100384Speter CP(ru, ru32, ru_isrss); 112100384Speter CP(ru, ru32, ru_minflt); 113100384Speter CP(ru, ru32, ru_majflt); 114100384Speter CP(ru, ru32, ru_nswap); 115100384Speter CP(ru, ru32, ru_inblock); 116100384Speter CP(ru, ru32, ru_oublock); 117100384Speter CP(ru, ru32, ru_msgsnd); 118100384Speter CP(ru, ru32, ru_msgrcv); 119100384Speter CP(ru, ru32, ru_nsignals); 120100384Speter CP(ru, ru32, ru_nvcsw); 121100384Speter CP(ru, ru32, ru_nivcsw); 122127140Sjhb error = copyout(&ru32, uap->rusage, sizeof(ru32)); 123100384Speter } 124100384Speter return (error); 125100384Speter} 126100384Speter 127128597Smarcel#ifdef COMPAT_FREEBSD4 128100384Speterstatic void 129100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out) 130100384Speter{ 131100384Speter CP(*in, *out, f_bsize); 132100384Speter CP(*in, *out, f_iosize); 133100384Speter CP(*in, *out, f_blocks); 134100384Speter CP(*in, *out, f_bfree); 135100384Speter CP(*in, *out, f_bavail); 136100384Speter CP(*in, *out, f_files); 137100384Speter CP(*in, *out, f_ffree); 138100384Speter CP(*in, *out, f_fsid); 139100384Speter CP(*in, *out, f_owner); 140100384Speter CP(*in, *out, f_type); 141100384Speter CP(*in, *out, f_flags); 142100384Speter CP(*in, *out, f_flags); 143100384Speter CP(*in, *out, f_syncwrites); 144100384Speter CP(*in, *out, f_asyncwrites); 145100384Speter bcopy(in->f_fstypename, 146100384Speter out->f_fstypename, MFSNAMELEN); 147100384Speter bcopy(in->f_mntonname, 148128260Speter out->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 149100384Speter CP(*in, *out, f_syncreads); 150100384Speter CP(*in, *out, f_asyncreads); 151100384Speter bcopy(in->f_mntfromname, 152128260Speter out->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 153100384Speter} 154128597Smarcel#endif 155100384Speter 156128597Smarcel#ifdef COMPAT_FREEBSD4 157100384Speterint 158128260Speterfreebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap) 159100384Speter{ 160100384Speter int error; 161100384Speter caddr_t sg; 162100384Speter struct statfs32 *sp32, stat32; 163100384Speter struct statfs *sp = NULL, stat; 164100384Speter int maxcount, count, i; 165100384Speter 166107849Salfred sp32 = uap->buf; 167107849Salfred maxcount = uap->bufsize / sizeof(struct statfs32); 168100384Speter 169100384Speter if (sp32) { 170100384Speter sg = stackgap_init(); 171100384Speter sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount); 172107849Salfred uap->buf = (struct statfs32 *)sp; 173100384Speter } 174100384Speter error = getfsstat(td, (struct getfsstat_args *) uap); 175100384Speter if (sp32 && !error) { 176100384Speter count = td->td_retval[0]; 177100384Speter for (i = 0; i < count; i++) { 178100384Speter error = copyin(&sp[i], &stat, sizeof(stat)); 179100384Speter if (error) 180100384Speter return (error); 181100384Speter copy_statfs(&stat, &stat32); 182100384Speter error = copyout(&stat32, &sp32[i], sizeof(stat32)); 183100384Speter if (error) 184100384Speter return (error); 185100384Speter } 186100384Speter } 187100384Speter return (error); 188100384Speter} 189128597Smarcel#endif 190100384Speter 191100384Speterstruct sigaltstack32 { 192100384Speter u_int32_t ss_sp; 193100384Speter u_int32_t ss_size; 194100384Speter int ss_flags; 195100384Speter}; 196100384Speter 197121719SpeterCTASSERT(sizeof(struct sigaltstack32) == 12); 198121719Speter 199100384Speterint 200119333Speterfreebsd32_sigaltstack(struct thread *td, 201119333Speter struct freebsd32_sigaltstack_args *uap) 202100384Speter{ 203113859Sjhb struct sigaltstack32 s32; 204113859Sjhb struct sigaltstack ss, oss, *ssp; 205100384Speter int error; 206100384Speter 207113859Sjhb if (uap->ss != NULL) { 208113859Sjhb error = copyin(uap->ss, &s32, sizeof(s32)); 209100384Speter if (error) 210100384Speter return (error); 211113859Sjhb PTRIN_CP(s32, ss, ss_sp); 212113859Sjhb CP(s32, ss, ss_size); 213113859Sjhb CP(s32, ss, ss_flags); 214113859Sjhb ssp = &ss; 215113859Sjhb } else 216113859Sjhb ssp = NULL; 217113859Sjhb error = kern_sigaltstack(td, ssp, &oss); 218113859Sjhb if (error == 0 && uap->oss != NULL) { 219113859Sjhb PTROUT_CP(oss, s32, ss_sp); 220113859Sjhb CP(oss, s32, ss_size); 221113859Sjhb CP(oss, s32, ss_flags); 222113859Sjhb error = copyout(&s32, uap->oss, sizeof(s32)); 223100384Speter } 224100384Speter return (error); 225100384Speter} 226100384Speter 227100384Speterint 228119333Speterfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) 229100384Speter{ 230100384Speter int error; 231100384Speter caddr_t sg; 232100384Speter struct execve_args ap; 233100384Speter u_int32_t *p32, arg; 234122253Speter char **p, *p64; 235100384Speter int count; 236100384Speter 237100384Speter sg = stackgap_init(); 238107849Salfred ap.fname = uap->fname; 239100384Speter 240107849Salfred if (uap->argv) { 241100384Speter count = 0; 242107849Salfred p32 = uap->argv; 243100384Speter do { 244100384Speter error = copyin(p32++, &arg, sizeof(arg)); 245100384Speter if (error) 246100384Speter return error; 247100384Speter count++; 248100384Speter } while (arg != 0); 249100384Speter p = stackgap_alloc(&sg, count * sizeof(char *)); 250107849Salfred ap.argv = p; 251107849Salfred p32 = uap->argv; 252100384Speter do { 253100384Speter error = copyin(p32++, &arg, sizeof(arg)); 254100384Speter if (error) 255100384Speter return error; 256122253Speter p64 = PTRIN(arg); 257122253Speter error = copyout(&p64, p++, sizeof(p64)); 258122253Speter if (error) 259122253Speter return error; 260100384Speter } while (arg != 0); 261100384Speter } 262107849Salfred if (uap->envv) { 263100384Speter count = 0; 264107849Salfred p32 = uap->envv; 265100384Speter do { 266100384Speter error = copyin(p32++, &arg, sizeof(arg)); 267100384Speter if (error) 268100384Speter return error; 269100384Speter count++; 270100384Speter } while (arg != 0); 271100384Speter p = stackgap_alloc(&sg, count * sizeof(char *)); 272107849Salfred ap.envv = p; 273107849Salfred p32 = uap->envv; 274100384Speter do { 275100384Speter error = copyin(p32++, &arg, sizeof(arg)); 276100384Speter if (error) 277100384Speter return error; 278122253Speter p64 = PTRIN(arg); 279122253Speter error = copyout(&p64, p++, sizeof(p64)); 280122253Speter if (error) 281122253Speter return error; 282100384Speter } while (arg != 0); 283100384Speter } 284100384Speter 285100384Speter return execve(td, &ap); 286100384Speter} 287100384Speter 288114987Speter#ifdef __ia64__ 289100384Speterstatic int 290119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 291119333Speter int prot, int fd, off_t pos) 292100384Speter{ 293100384Speter vm_map_t map; 294100384Speter vm_map_entry_t entry; 295100384Speter int rv; 296100384Speter 297100384Speter map = &td->td_proc->p_vmspace->vm_map; 298100384Speter if (fd != -1) 299100384Speter prot |= VM_PROT_WRITE; 300100384Speter 301100384Speter if (vm_map_lookup_entry(map, start, &entry)) { 302100384Speter if ((entry->protection & prot) != prot) { 303100384Speter rv = vm_map_protect(map, 304100384Speter trunc_page(start), 305100384Speter round_page(end), 306100384Speter entry->protection | prot, 307100384Speter FALSE); 308100384Speter if (rv != KERN_SUCCESS) 309100384Speter return (EINVAL); 310100384Speter } 311100384Speter } else { 312100384Speter vm_offset_t addr = trunc_page(start); 313100384Speter rv = vm_map_find(map, 0, 0, 314100384Speter &addr, PAGE_SIZE, FALSE, prot, 315100384Speter VM_PROT_ALL, 0); 316100384Speter if (rv != KERN_SUCCESS) 317100384Speter return (EINVAL); 318100384Speter } 319100384Speter 320100384Speter if (fd != -1) { 321100384Speter struct pread_args r; 322107849Salfred r.fd = fd; 323107849Salfred r.buf = (void *) start; 324107849Salfred r.nbyte = end - start; 325107849Salfred r.offset = pos; 326100384Speter return (pread(td, &r)); 327100384Speter } else { 328100384Speter while (start < end) { 329100384Speter subyte((void *) start, 0); 330100384Speter start++; 331100384Speter } 332100384Speter return (0); 333100384Speter } 334100384Speter} 335114987Speter#endif 336100384Speter 337100384Speterint 338119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) 339100384Speter{ 340100384Speter struct mmap_args ap; 341107849Salfred vm_offset_t addr = (vm_offset_t) uap->addr; 342107849Salfred vm_size_t len = uap->len; 343107849Salfred int prot = uap->prot; 344107849Salfred int flags = uap->flags; 345107849Salfred int fd = uap->fd; 346107849Salfred off_t pos = (uap->poslo 347107849Salfred | ((off_t)uap->poshi << 32)); 348114987Speter#ifdef __ia64__ 349100384Speter vm_size_t pageoff; 350100384Speter int error; 351100384Speter 352100384Speter /* 353100384Speter * Attempt to handle page size hassles. 354100384Speter */ 355100384Speter pageoff = (pos & PAGE_MASK); 356100384Speter if (flags & MAP_FIXED) { 357100384Speter vm_offset_t start, end; 358100384Speter start = addr; 359100384Speter end = addr + len; 360100384Speter 361100384Speter if (start != trunc_page(start)) { 362119333Speter error = freebsd32_mmap_partial(td, start, 363119333Speter round_page(start), prot, 364119333Speter fd, pos); 365100384Speter if (fd != -1) 366100384Speter pos += round_page(start) - start; 367100384Speter start = round_page(start); 368100384Speter } 369100384Speter if (end != round_page(end)) { 370100384Speter vm_offset_t t = trunc_page(end); 371119333Speter error = freebsd32_mmap_partial(td, t, end, 372100384Speter prot, fd, 373100384Speter pos + t - start); 374100384Speter end = trunc_page(end); 375100384Speter } 376100384Speter if (end > start && fd != -1 && (pos & PAGE_MASK)) { 377100384Speter /* 378100384Speter * We can't map this region at all. The specified 379100384Speter * address doesn't have the same alignment as the file 380100384Speter * position. Fake the mapping by simply reading the 381100384Speter * entire region into memory. First we need to make 382100384Speter * sure the region exists. 383100384Speter */ 384100384Speter vm_map_t map; 385100384Speter struct pread_args r; 386100384Speter int rv; 387100384Speter 388100384Speter prot |= VM_PROT_WRITE; 389100384Speter map = &td->td_proc->p_vmspace->vm_map; 390100384Speter rv = vm_map_remove(map, start, end); 391100384Speter if (rv != KERN_SUCCESS) 392100384Speter return (EINVAL); 393100384Speter rv = vm_map_find(map, 0, 0, 394100384Speter &start, end - start, FALSE, 395100384Speter prot, VM_PROT_ALL, 0); 396100384Speter if (rv != KERN_SUCCESS) 397100384Speter return (EINVAL); 398107849Salfred r.fd = fd; 399107849Salfred r.buf = (void *) start; 400107849Salfred r.nbyte = end - start; 401107849Salfred r.offset = pos; 402100384Speter error = pread(td, &r); 403100384Speter if (error) 404100384Speter return (error); 405100384Speter 406100384Speter td->td_retval[0] = addr; 407100384Speter return (0); 408100384Speter } 409100384Speter if (end == start) { 410100384Speter /* 411100384Speter * After dealing with the ragged ends, there 412100384Speter * might be none left. 413100384Speter */ 414100384Speter td->td_retval[0] = addr; 415100384Speter return (0); 416100384Speter } 417100384Speter addr = start; 418100384Speter len = end - start; 419100384Speter } 420114987Speter#endif 421100384Speter 422107849Salfred ap.addr = (void *) addr; 423107849Salfred ap.len = len; 424107849Salfred ap.prot = prot; 425107849Salfred ap.flags = flags; 426107849Salfred ap.fd = fd; 427107849Salfred ap.pos = pos; 428100384Speter 429100384Speter return (mmap(td, &ap)); 430100384Speter} 431100384Speter 432100384Speterstruct itimerval32 { 433100384Speter struct timeval32 it_interval; 434100384Speter struct timeval32 it_value; 435100384Speter}; 436100384Speter 437121719SpeterCTASSERT(sizeof(struct itimerval32) == 16); 438121719Speter 439100384Speterint 440119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) 441100384Speter{ 442100384Speter int error; 443100384Speter caddr_t sg; 444100384Speter struct itimerval32 *p32, *op32, s32; 445100384Speter struct itimerval *p = NULL, *op = NULL, s; 446100384Speter 447107849Salfred p32 = uap->itv; 448100384Speter if (p32) { 449100384Speter sg = stackgap_init(); 450100384Speter p = stackgap_alloc(&sg, sizeof(struct itimerval)); 451107849Salfred uap->itv = (struct itimerval32 *)p; 452100384Speter error = copyin(p32, &s32, sizeof(s32)); 453100384Speter if (error) 454100384Speter return (error); 455100384Speter TV_CP(s32, s, it_interval); 456100384Speter TV_CP(s32, s, it_value); 457100384Speter error = copyout(&s, p, sizeof(s)); 458100384Speter if (error) 459100384Speter return (error); 460100384Speter } 461107849Salfred op32 = uap->oitv; 462100384Speter if (op32) { 463100384Speter sg = stackgap_init(); 464100384Speter op = stackgap_alloc(&sg, sizeof(struct itimerval)); 465107849Salfred uap->oitv = (struct itimerval32 *)op; 466100384Speter } 467100384Speter error = setitimer(td, (struct setitimer_args *) uap); 468100384Speter if (error) 469100384Speter return (error); 470100384Speter if (op32) { 471100384Speter error = copyin(op, &s, sizeof(s)); 472100384Speter if (error) 473100384Speter return (error); 474100384Speter TV_CP(s, s32, it_interval); 475100384Speter TV_CP(s, s32, it_value); 476100384Speter error = copyout(&s32, op32, sizeof(s32)); 477100384Speter } 478100384Speter return (error); 479100384Speter} 480100384Speter 481100384Speterint 482125171Speterfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap) 483125171Speter{ 484125171Speter int error; 485125171Speter caddr_t sg; 486125171Speter struct itimerval32 *p32, s32; 487125171Speter struct itimerval *p = NULL, s; 488125171Speter 489125171Speter p32 = uap->itv; 490125171Speter if (p32) { 491125171Speter sg = stackgap_init(); 492125171Speter p = stackgap_alloc(&sg, sizeof(struct itimerval)); 493125171Speter uap->itv = (struct itimerval32 *)p; 494125171Speter } 495125171Speter error = getitimer(td, (struct getitimer_args *) uap); 496125171Speter if (error) 497125171Speter return (error); 498125171Speter if (p32) { 499125171Speter error = copyin(p, &s, sizeof(s)); 500125171Speter if (error) 501125171Speter return (error); 502125171Speter TV_CP(s, s32, it_interval); 503125171Speter TV_CP(s, s32, it_value); 504125171Speter error = copyout(&s32, p32, sizeof(s32)); 505125171Speter } 506125171Speter return (error); 507125171Speter} 508125171Speter 509125171Speterint 510119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap) 511100384Speter{ 512100384Speter int error; 513100384Speter caddr_t sg; 514100384Speter struct timeval32 *p32, s32; 515100384Speter struct timeval *p = NULL, s; 516100384Speter 517107849Salfred p32 = uap->tv; 518100384Speter if (p32) { 519100384Speter sg = stackgap_init(); 520100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 521107849Salfred uap->tv = (struct timeval32 *)p; 522100384Speter error = copyin(p32, &s32, sizeof(s32)); 523100384Speter if (error) 524100384Speter return (error); 525100384Speter CP(s32, s, tv_sec); 526100384Speter CP(s32, s, tv_usec); 527100384Speter error = copyout(&s, p, sizeof(s)); 528100384Speter if (error) 529100384Speter return (error); 530100384Speter } 531100384Speter /* 532100384Speter * XXX big-endian needs to convert the fd_sets too. 533100384Speter */ 534100384Speter return (select(td, (struct select_args *) uap)); 535100384Speter} 536100384Speter 537114987Speterstruct kevent32 { 538114987Speter u_int32_t ident; /* identifier for this event */ 539114987Speter short filter; /* filter for event */ 540114987Speter u_short flags; 541114987Speter u_int fflags; 542114987Speter int32_t data; 543114987Speter u_int32_t udata; /* opaque user data identifier */ 544114987Speter}; 545114987Speter 546121719SpeterCTASSERT(sizeof(struct kevent32) == 20); 547121719Speter 548100384Speterint 549119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) 550114987Speter{ 551114987Speter int error; 552114987Speter caddr_t sg; 553114987Speter struct timespec32 ts32; 554114987Speter struct timespec ts; 555114987Speter struct kevent32 ks32; 556114987Speter struct kevent *ks; 557114987Speter struct kevent_args a; 558114987Speter int i; 559114987Speter 560114987Speter sg = stackgap_init(); 561114987Speter 562114987Speter a.fd = uap->fd; 563114987Speter a.changelist = uap->changelist; 564114987Speter a.nchanges = uap->nchanges; 565114987Speter a.eventlist = uap->eventlist; 566114987Speter a.nevents = uap->nevents; 567114987Speter a.timeout = NULL; 568114987Speter 569114987Speter if (uap->timeout) { 570114987Speter a.timeout = stackgap_alloc(&sg, sizeof(struct timespec)); 571114987Speter error = copyin(uap->timeout, &ts32, sizeof(ts32)); 572114987Speter if (error) 573114987Speter return (error); 574114987Speter CP(ts32, ts, tv_sec); 575114987Speter CP(ts32, ts, tv_nsec); 576114987Speter error = copyout(&ts, (void *)(uintptr_t)a.timeout, sizeof(ts)); 577114987Speter if (error) 578114987Speter return (error); 579114987Speter } 580114987Speter if (uap->changelist) { 581119333Speter a.changelist = (struct kevent *)stackgap_alloc(&sg, 582119333Speter uap->nchanges * sizeof(struct kevent)); 583114987Speter for (i = 0; i < uap->nchanges; i++) { 584119333Speter error = copyin(&uap->changelist[i], &ks32, 585119333Speter sizeof(ks32)); 586114987Speter if (error) 587114987Speter return (error); 588114987Speter ks = (struct kevent *)(uintptr_t)&a.changelist[i]; 589114987Speter CP(ks32, *ks, ident); 590114987Speter CP(ks32, *ks, filter); 591114987Speter CP(ks32, *ks, flags); 592114987Speter CP(ks32, *ks, fflags); 593114987Speter CP(ks32, *ks, data); 594114987Speter PTRIN_CP(ks32, *ks, udata); 595114987Speter } 596114987Speter } 597114987Speter if (uap->eventlist) { 598119333Speter a.eventlist = stackgap_alloc(&sg, 599119333Speter uap->nevents * sizeof(struct kevent)); 600114987Speter } 601114987Speter error = kevent(td, &a); 602114987Speter if (uap->eventlist && error > 0) { 603114987Speter for (i = 0; i < error; i++) { 604114987Speter ks = &a.eventlist[i]; 605114987Speter CP(*ks, ks32, ident); 606114987Speter CP(*ks, ks32, filter); 607114987Speter CP(*ks, ks32, flags); 608114987Speter CP(*ks, ks32, fflags); 609114987Speter CP(*ks, ks32, data); 610114987Speter PTROUT_CP(*ks, ks32, udata); 611119333Speter error = copyout(&ks32, &uap->eventlist[i], 612119333Speter sizeof(ks32)); 613114987Speter if (error) 614114987Speter return (error); 615114987Speter } 616114987Speter } 617114987Speter return error; 618114987Speter} 619114987Speter 620114987Speterint 621119333Speterfreebsd32_gettimeofday(struct thread *td, 622119333Speter struct freebsd32_gettimeofday_args *uap) 623100384Speter{ 624123425Speter struct timeval atv; 625123425Speter struct timeval32 atv32; 626123425Speter struct timezone rtz; 627123425Speter int error = 0; 628100384Speter 629123425Speter if (uap->tp) { 630123425Speter microtime(&atv); 631123425Speter CP(atv, atv32, tv_sec); 632123425Speter CP(atv, atv32, tv_usec); 633123425Speter error = copyout(&atv32, uap->tp, sizeof (atv32)); 634100384Speter } 635123425Speter if (error == 0 && uap->tzp != NULL) { 636123425Speter rtz.tz_minuteswest = tz_minuteswest; 637123425Speter rtz.tz_dsttime = tz_dsttime; 638123425Speter error = copyout(&rtz, uap->tzp, sizeof (rtz)); 639100384Speter } 640100384Speter return (error); 641100384Speter} 642100384Speter 643100384Speterint 644119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) 645100384Speter{ 646136152Sjhb struct rusage32 s32; 647136152Sjhb struct rusage s; 648100384Speter int error; 649100384Speter 650136152Sjhb error = kern_getrusage(td, uap->who, &s); 651100384Speter if (error) 652100384Speter return (error); 653136152Sjhb if (uap->rusage != NULL) { 654100384Speter TV_CP(s, s32, ru_utime); 655100384Speter TV_CP(s, s32, ru_stime); 656100384Speter CP(s, s32, ru_maxrss); 657100384Speter CP(s, s32, ru_ixrss); 658100384Speter CP(s, s32, ru_idrss); 659100384Speter CP(s, s32, ru_isrss); 660100384Speter CP(s, s32, ru_minflt); 661100384Speter CP(s, s32, ru_majflt); 662100384Speter CP(s, s32, ru_nswap); 663100384Speter CP(s, s32, ru_inblock); 664100384Speter CP(s, s32, ru_oublock); 665100384Speter CP(s, s32, ru_msgsnd); 666100384Speter CP(s, s32, ru_msgrcv); 667100384Speter CP(s, s32, ru_nsignals); 668100384Speter CP(s, s32, ru_nvcsw); 669100384Speter CP(s, s32, ru_nivcsw); 670136152Sjhb error = copyout(&s32, uap->rusage, sizeof(s32)); 671100384Speter } 672100384Speter return (error); 673100384Speter} 674100384Speter 675100384Speterstruct iovec32 { 676100384Speter u_int32_t iov_base; 677100384Speter int iov_len; 678100384Speter}; 679100384Speter#define STACKGAPLEN 400 680100384Speter 681121719SpeterCTASSERT(sizeof(struct iovec32) == 8); 682121719Speter 683100384Speterint 684119333Speterfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) 685100384Speter{ 686100384Speter int error, osize, nsize, i; 687100384Speter caddr_t sg; 688100384Speter struct readv_args /* { 689100384Speter syscallarg(int) fd; 690100384Speter syscallarg(struct iovec *) iovp; 691100384Speter syscallarg(u_int) iovcnt; 692100384Speter } */ a; 693100384Speter struct iovec32 *oio; 694100384Speter struct iovec *nio; 695100384Speter 696100384Speter sg = stackgap_init(); 697100384Speter 698107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 699100384Speter return (EINVAL); 700100384Speter 701107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 702107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 703100384Speter 704111119Simp oio = malloc(osize, M_TEMP, M_WAITOK); 705111119Simp nio = malloc(nsize, M_TEMP, M_WAITOK); 706100384Speter 707100384Speter error = 0; 708107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 709100384Speter goto punt; 710107849Salfred for (i = 0; i < uap->iovcnt; i++) { 711100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 712100384Speter nio[i].iov_len = oio[i].iov_len; 713100384Speter } 714100384Speter 715107849Salfred a.fd = uap->fd; 716107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 717107849Salfred a.iovcnt = uap->iovcnt; 718100384Speter 719107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 720100384Speter goto punt; 721100384Speter error = readv(td, &a); 722100384Speter 723100384Speterpunt: 724100384Speter free(oio, M_TEMP); 725100384Speter free(nio, M_TEMP); 726100384Speter return (error); 727100384Speter} 728100384Speter 729100384Speterint 730119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) 731100384Speter{ 732100384Speter int error, i, nsize, osize; 733100384Speter caddr_t sg; 734100384Speter struct writev_args /* { 735100384Speter syscallarg(int) fd; 736100384Speter syscallarg(struct iovec *) iovp; 737100384Speter syscallarg(u_int) iovcnt; 738100384Speter } */ a; 739100384Speter struct iovec32 *oio; 740100384Speter struct iovec *nio; 741100384Speter 742100384Speter sg = stackgap_init(); 743100384Speter 744107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 745100384Speter return (EINVAL); 746100384Speter 747107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 748107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 749100384Speter 750111119Simp oio = malloc(osize, M_TEMP, M_WAITOK); 751111119Simp nio = malloc(nsize, M_TEMP, M_WAITOK); 752100384Speter 753100384Speter error = 0; 754107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 755100384Speter goto punt; 756107849Salfred for (i = 0; i < uap->iovcnt; i++) { 757100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 758100384Speter nio[i].iov_len = oio[i].iov_len; 759100384Speter } 760100384Speter 761107849Salfred a.fd = uap->fd; 762107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 763107849Salfred a.iovcnt = uap->iovcnt; 764100384Speter 765107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 766100384Speter goto punt; 767100384Speter error = writev(td, &a); 768100384Speter 769100384Speterpunt: 770100384Speter free(oio, M_TEMP); 771100384Speter free(nio, M_TEMP); 772100384Speter return (error); 773100384Speter} 774100384Speter 775100384Speterint 776119333Speterfreebsd32_settimeofday(struct thread *td, 777119333Speter struct freebsd32_settimeofday_args *uap) 778100384Speter{ 779100384Speter int error; 780100384Speter caddr_t sg; 781100384Speter struct timeval32 *p32, s32; 782100384Speter struct timeval *p = NULL, s; 783100384Speter 784107849Salfred p32 = uap->tv; 785100384Speter if (p32) { 786100384Speter sg = stackgap_init(); 787100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 788107849Salfred uap->tv = (struct timeval32 *)p; 789100384Speter error = copyin(p32, &s32, sizeof(s32)); 790100384Speter if (error) 791100384Speter return (error); 792100384Speter CP(s32, s, tv_sec); 793100384Speter CP(s32, s, tv_usec); 794100384Speter error = copyout(&s, p, sizeof(s)); 795100384Speter if (error) 796100384Speter return (error); 797100384Speter } 798100384Speter return (settimeofday(td, (struct settimeofday_args *) uap)); 799100384Speter} 800100384Speter 801100384Speterint 802119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) 803100384Speter{ 804100384Speter int error; 805100384Speter caddr_t sg; 806100384Speter struct timeval32 *p32, s32[2]; 807100384Speter struct timeval *p = NULL, s[2]; 808100384Speter 809107849Salfred p32 = uap->tptr; 810100384Speter if (p32) { 811100384Speter sg = stackgap_init(); 812100384Speter p = stackgap_alloc(&sg, 2*sizeof(struct timeval)); 813107849Salfred uap->tptr = (struct timeval32 *)p; 814100384Speter error = copyin(p32, s32, sizeof(s32)); 815100384Speter if (error) 816100384Speter return (error); 817100384Speter CP(s32[0], s[0], tv_sec); 818100384Speter CP(s32[0], s[0], tv_usec); 819100384Speter CP(s32[1], s[1], tv_sec); 820100384Speter CP(s32[1], s[1], tv_usec); 821100384Speter error = copyout(s, p, sizeof(s)); 822100384Speter if (error) 823100384Speter return (error); 824100384Speter } 825100384Speter return (utimes(td, (struct utimes_args *) uap)); 826100384Speter} 827100384Speter 828100384Speterint 829119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) 830100384Speter{ 831100384Speter int error; 832100384Speter caddr_t sg; 833100384Speter struct timeval32 *p32, *op32, s32; 834100384Speter struct timeval *p = NULL, *op = NULL, s; 835100384Speter 836107849Salfred p32 = uap->delta; 837100384Speter if (p32) { 838100384Speter sg = stackgap_init(); 839100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 840107849Salfred uap->delta = (struct timeval32 *)p; 841100384Speter error = copyin(p32, &s32, sizeof(s32)); 842100384Speter if (error) 843100384Speter return (error); 844100384Speter CP(s32, s, tv_sec); 845100384Speter CP(s32, s, tv_usec); 846100384Speter error = copyout(&s, p, sizeof(s)); 847100384Speter if (error) 848100384Speter return (error); 849100384Speter } 850107849Salfred op32 = uap->olddelta; 851100384Speter if (op32) { 852100384Speter sg = stackgap_init(); 853100384Speter op = stackgap_alloc(&sg, sizeof(struct timeval)); 854107849Salfred uap->olddelta = (struct timeval32 *)op; 855100384Speter } 856100384Speter error = utimes(td, (struct utimes_args *) uap); 857100384Speter if (error) 858100384Speter return error; 859100384Speter if (op32) { 860100384Speter error = copyin(op, &s, sizeof(s)); 861100384Speter if (error) 862100384Speter return (error); 863100384Speter CP(s, s32, tv_sec); 864100384Speter CP(s, s32, tv_usec); 865100384Speter error = copyout(&s32, op32, sizeof(s32)); 866100384Speter } 867100384Speter return (error); 868100384Speter} 869100384Speter 870128597Smarcel#ifdef COMPAT_FREEBSD4 871100384Speterint 872128260Speterfreebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap) 873100384Speter{ 874100384Speter int error; 875100384Speter caddr_t sg; 876100384Speter struct statfs32 *p32, s32; 877100384Speter struct statfs *p = NULL, s; 878100384Speter 879107849Salfred p32 = uap->buf; 880100384Speter if (p32) { 881100384Speter sg = stackgap_init(); 882100384Speter p = stackgap_alloc(&sg, sizeof(struct statfs)); 883107849Salfred uap->buf = (struct statfs32 *)p; 884100384Speter } 885100384Speter error = statfs(td, (struct statfs_args *) uap); 886100384Speter if (error) 887100384Speter return (error); 888100384Speter if (p32) { 889100384Speter error = copyin(p, &s, sizeof(s)); 890100384Speter if (error) 891100384Speter return (error); 892100384Speter copy_statfs(&s, &s32); 893100384Speter error = copyout(&s32, p32, sizeof(s32)); 894100384Speter } 895100384Speter return (error); 896100384Speter} 897128597Smarcel#endif 898100384Speter 899128597Smarcel#ifdef COMPAT_FREEBSD4 900100384Speterint 901128260Speterfreebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap) 902100384Speter{ 903100384Speter int error; 904100384Speter caddr_t sg; 905100384Speter struct statfs32 *p32, s32; 906100384Speter struct statfs *p = NULL, s; 907100384Speter 908107849Salfred p32 = uap->buf; 909100384Speter if (p32) { 910100384Speter sg = stackgap_init(); 911100384Speter p = stackgap_alloc(&sg, sizeof(struct statfs)); 912107849Salfred uap->buf = (struct statfs32 *)p; 913100384Speter } 914100384Speter error = fstatfs(td, (struct fstatfs_args *) uap); 915100384Speter if (error) 916100384Speter return (error); 917100384Speter if (p32) { 918100384Speter error = copyin(p, &s, sizeof(s)); 919100384Speter if (error) 920100384Speter return (error); 921100384Speter copy_statfs(&s, &s32); 922100384Speter error = copyout(&s32, p32, sizeof(s32)); 923100384Speter } 924100384Speter return (error); 925100384Speter} 926128597Smarcel#endif 927100384Speter 928128597Smarcel#ifdef COMPAT_FREEBSD4 929100384Speterint 930128260Speterfreebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap) 931128260Speter{ 932128260Speter int error; 933128260Speter caddr_t sg; 934128260Speter struct statfs32 *p32, s32; 935128260Speter struct statfs *p = NULL, s; 936128260Speter 937128260Speter p32 = uap->buf; 938128260Speter if (p32) { 939128260Speter sg = stackgap_init(); 940128260Speter p = stackgap_alloc(&sg, sizeof(struct statfs)); 941128260Speter uap->buf = (struct statfs32 *)p; 942128260Speter } 943128260Speter error = fhstatfs(td, (struct fhstatfs_args *) uap); 944128260Speter if (error) 945128260Speter return (error); 946128260Speter if (p32) { 947128260Speter error = copyin(p, &s, sizeof(s)); 948128260Speter if (error) 949128260Speter return (error); 950128260Speter copy_statfs(&s, &s32); 951128260Speter error = copyout(&s32, p32, sizeof(s32)); 952128260Speter } 953128260Speter return (error); 954128260Speter} 955128597Smarcel#endif 956128260Speter 957128260Speterint 958119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) 959100384Speter{ 960100384Speter /* 961100384Speter * Vector through to semsys if it is loaded. 962100384Speter */ 963100384Speter return sysent[169].sy_call(td, uap); 964100384Speter} 965100384Speter 966100384Speterint 967119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap) 968100384Speter{ 969100384Speter /* 970100384Speter * Vector through to msgsys if it is loaded. 971100384Speter */ 972100384Speter return sysent[170].sy_call(td, uap); 973100384Speter} 974100384Speter 975100384Speterint 976119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap) 977100384Speter{ 978100384Speter /* 979100384Speter * Vector through to shmsys if it is loaded. 980100384Speter */ 981100384Speter return sysent[171].sy_call(td, uap); 982100384Speter} 983100384Speter 984100384Speterint 985119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) 986100384Speter{ 987100384Speter struct pread_args ap; 988100384Speter 989107849Salfred ap.fd = uap->fd; 990107849Salfred ap.buf = uap->buf; 991107849Salfred ap.nbyte = uap->nbyte; 992119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 993100384Speter return (pread(td, &ap)); 994100384Speter} 995100384Speter 996100384Speterint 997119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) 998100384Speter{ 999100384Speter struct pwrite_args ap; 1000100384Speter 1001107849Salfred ap.fd = uap->fd; 1002107849Salfred ap.buf = uap->buf; 1003107849Salfred ap.nbyte = uap->nbyte; 1004119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1005100384Speter return (pwrite(td, &ap)); 1006100384Speter} 1007100384Speter 1008100384Speterint 1009119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) 1010100384Speter{ 1011100384Speter int error; 1012100384Speter struct lseek_args ap; 1013100384Speter off_t pos; 1014100384Speter 1015107849Salfred ap.fd = uap->fd; 1016119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1017107849Salfred ap.whence = uap->whence; 1018100384Speter error = lseek(td, &ap); 1019100384Speter /* Expand the quad return into two parts for eax and edx */ 1020100384Speter pos = *(off_t *)(td->td_retval); 1021100384Speter td->td_retval[0] = pos & 0xffffffff; /* %eax */ 1022100384Speter td->td_retval[1] = pos >> 32; /* %edx */ 1023100384Speter return error; 1024100384Speter} 1025100384Speter 1026100384Speterint 1027119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) 1028100384Speter{ 1029100384Speter struct truncate_args ap; 1030100384Speter 1031107849Salfred ap.path = uap->path; 1032119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1033100384Speter return (truncate(td, &ap)); 1034100384Speter} 1035100384Speter 1036100384Speterint 1037119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 1038100384Speter{ 1039100384Speter struct ftruncate_args ap; 1040100384Speter 1041107849Salfred ap.fd = uap->fd; 1042119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1043100384Speter return (ftruncate(td, &ap)); 1044100384Speter} 1045100384Speter 1046104738Speter#ifdef COMPAT_FREEBSD4 1047100384Speterint 1048119333Speterfreebsd4_freebsd32_sendfile(struct thread *td, 1049119333Speter struct freebsd4_freebsd32_sendfile_args *uap) 1050104738Speter{ 1051104738Speter struct freebsd4_sendfile_args ap; 1052104738Speter 1053107849Salfred ap.fd = uap->fd; 1054107849Salfred ap.s = uap->s; 1055119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1056107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1057107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1058107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1059107849Salfred ap.flags = uap->flags; 1060104738Speter return (freebsd4_sendfile(td, &ap)); 1061104738Speter} 1062104738Speter#endif 1063104738Speter 1064104738Speterint 1065119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) 1066100384Speter{ 1067100384Speter struct sendfile_args ap; 1068100384Speter 1069107849Salfred ap.fd = uap->fd; 1070107849Salfred ap.s = uap->s; 1071119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1072107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1073107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1074107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1075107849Salfred ap.flags = uap->flags; 1076100384Speter return (sendfile(td, &ap)); 1077100384Speter} 1078100384Speter 1079100384Speterstruct stat32 { 1080130640Sphk dev_t st_dev; 1081100384Speter ino_t st_ino; 1082100384Speter mode_t st_mode; 1083100384Speter nlink_t st_nlink; 1084100384Speter uid_t st_uid; 1085100384Speter gid_t st_gid; 1086130640Sphk dev_t st_rdev; 1087100384Speter struct timespec32 st_atimespec; 1088100384Speter struct timespec32 st_mtimespec; 1089100384Speter struct timespec32 st_ctimespec; 1090100384Speter off_t st_size; 1091100384Speter int64_t st_blocks; 1092100384Speter u_int32_t st_blksize; 1093100384Speter u_int32_t st_flags; 1094100384Speter u_int32_t st_gen; 1095121719Speter struct timespec32 st_birthtimespec; 1096121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1097121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1098100384Speter}; 1099100384Speter 1100121719Speter 1101121719SpeterCTASSERT(sizeof(struct stat32) == 96); 1102121719Speter 1103100384Speterstatic void 1104100384Spetercopy_stat( struct stat *in, struct stat32 *out) 1105100384Speter{ 1106100384Speter CP(*in, *out, st_dev); 1107100384Speter CP(*in, *out, st_ino); 1108100384Speter CP(*in, *out, st_mode); 1109100384Speter CP(*in, *out, st_nlink); 1110100384Speter CP(*in, *out, st_uid); 1111100384Speter CP(*in, *out, st_gid); 1112100384Speter CP(*in, *out, st_rdev); 1113100384Speter TS_CP(*in, *out, st_atimespec); 1114100384Speter TS_CP(*in, *out, st_mtimespec); 1115100384Speter TS_CP(*in, *out, st_ctimespec); 1116100384Speter CP(*in, *out, st_size); 1117100384Speter CP(*in, *out, st_blocks); 1118100384Speter CP(*in, *out, st_blksize); 1119100384Speter CP(*in, *out, st_flags); 1120100384Speter CP(*in, *out, st_gen); 1121100384Speter} 1122100384Speter 1123100384Speterint 1124119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) 1125100384Speter{ 1126123746Speter struct stat sb; 1127123746Speter struct stat32 sb32; 1128100384Speter int error; 1129123746Speter struct nameidata nd; 1130100384Speter 1131123746Speter#ifdef LOOKUP_SHARED 1132123746Speter NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | NOOBJ, 1133123746Speter UIO_USERSPACE, uap->path, td); 1134123746Speter#else 1135123746Speter NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1136123746Speter uap->path, td); 1137123746Speter#endif 1138123746Speter if ((error = namei(&nd)) != 0) 1139123746Speter return (error); 1140123746Speter error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td); 1141123746Speter NDFREE(&nd, NDF_ONLY_PNBUF); 1142123746Speter vput(nd.ni_vp); 1143100384Speter if (error) 1144100384Speter return (error); 1145123746Speter copy_stat(&sb, &sb32); 1146123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1147100384Speter return (error); 1148100384Speter} 1149100384Speter 1150100384Speterint 1151119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) 1152100384Speter{ 1153123746Speter struct file *fp; 1154123746Speter struct stat ub; 1155123746Speter struct stat32 ub32; 1156100384Speter int error; 1157100384Speter 1158123746Speter if ((error = fget(td, uap->fd, &fp)) != 0) 1159123746Speter return (error); 1160123746Speter mtx_lock(&Giant); 1161123746Speter error = fo_stat(fp, &ub, td->td_ucred, td); 1162123746Speter mtx_unlock(&Giant); 1163123746Speter fdrop(fp, td); 1164100384Speter if (error) 1165100384Speter return (error); 1166123746Speter copy_stat(&ub, &ub32); 1167123746Speter error = copyout(&ub32, uap->ub, sizeof(ub32)); 1168100384Speter return (error); 1169100384Speter} 1170100384Speter 1171100384Speterint 1172119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) 1173100384Speter{ 1174100384Speter int error; 1175123746Speter struct vnode *vp; 1176123746Speter struct stat sb; 1177123746Speter struct stat32 sb32; 1178123746Speter struct nameidata nd; 1179100384Speter 1180123746Speter NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1181123746Speter uap->path, td); 1182123746Speter if ((error = namei(&nd)) != 0) 1183123746Speter return (error); 1184123746Speter vp = nd.ni_vp; 1185123746Speter error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td); 1186123746Speter NDFREE(&nd, NDF_ONLY_PNBUF); 1187123746Speter vput(vp); 1188100384Speter if (error) 1189100384Speter return (error); 1190123746Speter copy_stat(&sb, &sb32); 1191123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1192100384Speter return (error); 1193100384Speter} 1194100384Speter 1195100384Speter/* 1196100384Speter * MPSAFE 1197100384Speter */ 1198100384Speterint 1199119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) 1200100384Speter{ 1201100384Speter int error, name[CTL_MAXNAME]; 1202100384Speter size_t j, oldlen; 1203100384Speter 1204100384Speter if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1205100384Speter return (EINVAL); 1206100384Speter 1207100384Speter error = copyin(uap->name, &name, uap->namelen * sizeof(int)); 1208100384Speter if (error) 1209100384Speter return (error); 1210100384Speter 1211100384Speter mtx_lock(&Giant); 1212100384Speter 1213100384Speter if (uap->oldlenp) 1214100384Speter oldlen = fuword32(uap->oldlenp); 1215100384Speter else 1216100384Speter oldlen = 0; 1217100384Speter error = userland_sysctl(td, name, uap->namelen, 1218100384Speter uap->old, &oldlen, 1, 1219100384Speter uap->new, uap->newlen, &j); 1220100384Speter if (error && error != ENOMEM) 1221100384Speter goto done2; 1222100384Speter if (uap->oldlenp) { 1223100384Speter suword32(uap->oldlenp, j); 1224100384Speter } 1225100384Speterdone2: 1226100384Speter mtx_unlock(&Giant); 1227100384Speter return (error); 1228100384Speter} 1229100384Speter 1230100384Speterstruct sigaction32 { 1231100384Speter u_int32_t sa_u; 1232100384Speter int sa_flags; 1233100384Speter sigset_t sa_mask; 1234100384Speter}; 1235100384Speter 1236121719SpeterCTASSERT(sizeof(struct sigaction32) == 24); 1237121719Speter 1238100384Speterint 1239119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) 1240100384Speter{ 1241113859Sjhb struct sigaction32 s32; 1242113859Sjhb struct sigaction sa, osa, *sap; 1243100384Speter int error; 1244100384Speter 1245113859Sjhb if (uap->act) { 1246113859Sjhb error = copyin(uap->act, &s32, sizeof(s32)); 1247100384Speter if (error) 1248100384Speter return (error); 1249113859Sjhb sa.sa_handler = PTRIN(s32.sa_u); 1250113859Sjhb CP(s32, sa, sa_flags); 1251113859Sjhb CP(s32, sa, sa_mask); 1252113859Sjhb sap = &sa; 1253113859Sjhb } else 1254113859Sjhb sap = NULL; 1255113859Sjhb error = kern_sigaction(td, uap->sig, sap, &osa, 0); 1256113859Sjhb if (error != 0 && uap->oact != NULL) { 1257113859Sjhb s32.sa_u = PTROUT(osa.sa_handler); 1258113859Sjhb CP(osa, s32, sa_flags); 1259113859Sjhb CP(osa, s32, sa_mask); 1260113859Sjhb error = copyout(&s32, uap->oact, sizeof(s32)); 1261100384Speter } 1262100384Speter return (error); 1263100384Speter} 1264100384Speter 1265114987Speter#ifdef COMPAT_FREEBSD4 1266114987Speterint 1267119333Speterfreebsd4_freebsd32_sigaction(struct thread *td, 1268119333Speter struct freebsd4_freebsd32_sigaction_args *uap) 1269114987Speter{ 1270114987Speter struct sigaction32 s32; 1271114987Speter struct sigaction sa, osa, *sap; 1272114987Speter int error; 1273114987Speter 1274114987Speter if (uap->act) { 1275114987Speter error = copyin(uap->act, &s32, sizeof(s32)); 1276114987Speter if (error) 1277114987Speter return (error); 1278114987Speter sa.sa_handler = PTRIN(s32.sa_u); 1279114987Speter CP(s32, sa, sa_flags); 1280114987Speter CP(s32, sa, sa_mask); 1281114987Speter sap = &sa; 1282114987Speter } else 1283114987Speter sap = NULL; 1284114987Speter error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 1285114987Speter if (error != 0 && uap->oact != NULL) { 1286114987Speter s32.sa_u = PTROUT(osa.sa_handler); 1287114987Speter CP(osa, s32, sa_flags); 1288114987Speter CP(osa, s32, sa_mask); 1289114987Speter error = copyout(&s32, uap->oact, sizeof(s32)); 1290114987Speter } 1291114987Speter return (error); 1292114987Speter} 1293114987Speter#endif 1294114987Speter 1295100384Speter#if 0 1296100384Speter 1297100384Speterint 1298119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) 1299100384Speter{ 1300100384Speter int error; 1301100384Speter caddr_t sg; 1302100384Speter struct yyy32 *p32, s32; 1303100384Speter struct yyy *p = NULL, s; 1304100384Speter 1305107849Salfred p32 = uap->zzz; 1306100384Speter if (p32) { 1307100384Speter sg = stackgap_init(); 1308100384Speter p = stackgap_alloc(&sg, sizeof(struct yyy)); 1309107849Salfred uap->zzz = (struct yyy32 *)p; 1310100384Speter error = copyin(p32, &s32, sizeof(s32)); 1311100384Speter if (error) 1312100384Speter return (error); 1313100384Speter /* translate in */ 1314100384Speter error = copyout(&s, p, sizeof(s)); 1315100384Speter if (error) 1316100384Speter return (error); 1317100384Speter } 1318100384Speter error = xxx(td, (struct xxx_args *) uap); 1319100384Speter if (error) 1320100384Speter return (error); 1321100384Speter if (p32) { 1322100384Speter error = copyin(p, &s, sizeof(s)); 1323100384Speter if (error) 1324100384Speter return (error); 1325100384Speter /* translate out */ 1326100384Speter error = copyout(&s32, p32, sizeof(s32)); 1327100384Speter } 1328100384Speter return (error); 1329100384Speter} 1330100384Speter 1331100384Speter#endif 1332