freebsd32_misc.c revision 125171
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 125171 2004-01-28 23:45:48Z peter $"); 29118031Sobrien 30104738Speter#include "opt_compat.h" 31104738Speter 32100384Speter#include <sys/param.h> 33100384Speter#include <sys/systm.h> 34100384Speter#include <sys/bus.h> 35100384Speter#include <sys/exec.h> 36100384Speter#include <sys/fcntl.h> 37100384Speter#include <sys/filedesc.h> 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> 70100384Speter 71100384Speter#include <vm/vm.h> 72100384Speter#include <vm/vm_kern.h> 73100384Speter#include <vm/vm_param.h> 74100384Speter#include <vm/pmap.h> 75100384Speter#include <vm/vm_map.h> 76100384Speter#include <vm/vm_object.h> 77100384Speter#include <vm/vm_extern.h> 78100384Speter 79119333Speter#include <compat/freebsd32/freebsd32_util.h> 80119333Speter#include <compat/freebsd32/freebsd32.h> 81119333Speter#include <compat/freebsd32/freebsd32_proto.h> 82100384Speter 83121719SpeterCTASSERT(sizeof(struct timeval32) == 8); 84121719SpeterCTASSERT(sizeof(struct timespec32) == 8); 85121719SpeterCTASSERT(sizeof(struct statfs32) == 256); 86121719SpeterCTASSERT(sizeof(struct rusage32) == 72); 87121719Speter 88100384Speterint 89119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) 90100384Speter{ 91100384Speter int error; 92100384Speter caddr_t sg; 93100384Speter struct rusage32 *rusage32, ru32; 94100384Speter struct rusage *rusage = NULL, ru; 95100384Speter 96107849Salfred rusage32 = uap->rusage; 97100384Speter if (rusage32) { 98100384Speter sg = stackgap_init(); 99100384Speter rusage = stackgap_alloc(&sg, sizeof(struct rusage)); 100107849Salfred uap->rusage = (struct rusage32 *)rusage; 101100384Speter } 102100384Speter error = wait4(td, (struct wait_args *)uap); 103100384Speter if (error) 104100384Speter return (error); 105100384Speter if (rusage32 && (error = copyin(rusage, &ru, sizeof(ru)) == 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); 122100384Speter error = copyout(&ru32, rusage32, sizeof(ru32)); 123100384Speter } 124100384Speter return (error); 125100384Speter} 126100384Speter 127100384Speterstatic void 128100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out) 129100384Speter{ 130100384Speter CP(*in, *out, f_bsize); 131100384Speter CP(*in, *out, f_iosize); 132100384Speter CP(*in, *out, f_blocks); 133100384Speter CP(*in, *out, f_bfree); 134100384Speter CP(*in, *out, f_bavail); 135100384Speter CP(*in, *out, f_files); 136100384Speter CP(*in, *out, f_ffree); 137100384Speter CP(*in, *out, f_fsid); 138100384Speter CP(*in, *out, f_owner); 139100384Speter CP(*in, *out, f_type); 140100384Speter CP(*in, *out, f_flags); 141100384Speter CP(*in, *out, f_flags); 142100384Speter CP(*in, *out, f_syncwrites); 143100384Speter CP(*in, *out, f_asyncwrites); 144100384Speter bcopy(in->f_fstypename, 145100384Speter out->f_fstypename, MFSNAMELEN); 146100384Speter bcopy(in->f_mntonname, 147100384Speter out->f_mntonname, MNAMELEN); 148100384Speter CP(*in, *out, f_syncreads); 149100384Speter CP(*in, *out, f_asyncreads); 150100384Speter bcopy(in->f_mntfromname, 151100384Speter out->f_mntfromname, MNAMELEN); 152100384Speter} 153100384Speter 154100384Speterint 155119333Speterfreebsd32_getfsstat(struct thread *td, struct freebsd32_getfsstat_args *uap) 156100384Speter{ 157100384Speter int error; 158100384Speter caddr_t sg; 159100384Speter struct statfs32 *sp32, stat32; 160100384Speter struct statfs *sp = NULL, stat; 161100384Speter int maxcount, count, i; 162100384Speter 163107849Salfred sp32 = uap->buf; 164107849Salfred maxcount = uap->bufsize / sizeof(struct statfs32); 165100384Speter 166100384Speter if (sp32) { 167100384Speter sg = stackgap_init(); 168100384Speter sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount); 169107849Salfred uap->buf = (struct statfs32 *)sp; 170100384Speter } 171100384Speter error = getfsstat(td, (struct getfsstat_args *) uap); 172100384Speter if (sp32 && !error) { 173100384Speter count = td->td_retval[0]; 174100384Speter for (i = 0; i < count; i++) { 175100384Speter error = copyin(&sp[i], &stat, sizeof(stat)); 176100384Speter if (error) 177100384Speter return (error); 178100384Speter copy_statfs(&stat, &stat32); 179100384Speter error = copyout(&stat32, &sp32[i], sizeof(stat32)); 180100384Speter if (error) 181100384Speter return (error); 182100384Speter } 183100384Speter } 184100384Speter return (error); 185100384Speter} 186100384Speter 187100384Speterstruct sigaltstack32 { 188100384Speter u_int32_t ss_sp; 189100384Speter u_int32_t ss_size; 190100384Speter int ss_flags; 191100384Speter}; 192100384Speter 193121719SpeterCTASSERT(sizeof(struct sigaltstack32) == 12); 194121719Speter 195100384Speterint 196119333Speterfreebsd32_sigaltstack(struct thread *td, 197119333Speter struct freebsd32_sigaltstack_args *uap) 198100384Speter{ 199113859Sjhb struct sigaltstack32 s32; 200113859Sjhb struct sigaltstack ss, oss, *ssp; 201100384Speter int error; 202100384Speter 203113859Sjhb if (uap->ss != NULL) { 204113859Sjhb error = copyin(uap->ss, &s32, sizeof(s32)); 205100384Speter if (error) 206100384Speter return (error); 207113859Sjhb PTRIN_CP(s32, ss, ss_sp); 208113859Sjhb CP(s32, ss, ss_size); 209113859Sjhb CP(s32, ss, ss_flags); 210113859Sjhb ssp = &ss; 211113859Sjhb } else 212113859Sjhb ssp = NULL; 213113859Sjhb error = kern_sigaltstack(td, ssp, &oss); 214113859Sjhb if (error == 0 && uap->oss != NULL) { 215113859Sjhb PTROUT_CP(oss, s32, ss_sp); 216113859Sjhb CP(oss, s32, ss_size); 217113859Sjhb CP(oss, s32, ss_flags); 218113859Sjhb error = copyout(&s32, uap->oss, sizeof(s32)); 219100384Speter } 220100384Speter return (error); 221100384Speter} 222100384Speter 223100384Speterint 224119333Speterfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) 225100384Speter{ 226100384Speter int error; 227100384Speter caddr_t sg; 228100384Speter struct execve_args ap; 229100384Speter u_int32_t *p32, arg; 230122253Speter char **p, *p64; 231100384Speter int count; 232100384Speter 233100384Speter sg = stackgap_init(); 234107849Salfred ap.fname = uap->fname; 235100384Speter 236107849Salfred if (uap->argv) { 237100384Speter count = 0; 238107849Salfred p32 = uap->argv; 239100384Speter do { 240100384Speter error = copyin(p32++, &arg, sizeof(arg)); 241100384Speter if (error) 242100384Speter return error; 243100384Speter count++; 244100384Speter } while (arg != 0); 245100384Speter p = stackgap_alloc(&sg, count * sizeof(char *)); 246107849Salfred ap.argv = p; 247107849Salfred p32 = uap->argv; 248100384Speter do { 249100384Speter error = copyin(p32++, &arg, sizeof(arg)); 250100384Speter if (error) 251100384Speter return error; 252122253Speter p64 = PTRIN(arg); 253122253Speter error = copyout(&p64, p++, sizeof(p64)); 254122253Speter if (error) 255122253Speter return error; 256100384Speter } while (arg != 0); 257100384Speter } 258107849Salfred if (uap->envv) { 259100384Speter count = 0; 260107849Salfred p32 = uap->envv; 261100384Speter do { 262100384Speter error = copyin(p32++, &arg, sizeof(arg)); 263100384Speter if (error) 264100384Speter return error; 265100384Speter count++; 266100384Speter } while (arg != 0); 267100384Speter p = stackgap_alloc(&sg, count * sizeof(char *)); 268107849Salfred ap.envv = p; 269107849Salfred p32 = uap->envv; 270100384Speter do { 271100384Speter error = copyin(p32++, &arg, sizeof(arg)); 272100384Speter if (error) 273100384Speter return error; 274122253Speter p64 = PTRIN(arg); 275122253Speter error = copyout(&p64, p++, sizeof(p64)); 276122253Speter if (error) 277122253Speter return error; 278100384Speter } while (arg != 0); 279100384Speter } 280100384Speter 281100384Speter return execve(td, &ap); 282100384Speter} 283100384Speter 284114987Speter#ifdef __ia64__ 285100384Speterstatic int 286119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 287119333Speter int prot, int fd, off_t pos) 288100384Speter{ 289100384Speter vm_map_t map; 290100384Speter vm_map_entry_t entry; 291100384Speter int rv; 292100384Speter 293100384Speter map = &td->td_proc->p_vmspace->vm_map; 294100384Speter if (fd != -1) 295100384Speter prot |= VM_PROT_WRITE; 296100384Speter 297100384Speter if (vm_map_lookup_entry(map, start, &entry)) { 298100384Speter if ((entry->protection & prot) != prot) { 299100384Speter rv = vm_map_protect(map, 300100384Speter trunc_page(start), 301100384Speter round_page(end), 302100384Speter entry->protection | prot, 303100384Speter FALSE); 304100384Speter if (rv != KERN_SUCCESS) 305100384Speter return (EINVAL); 306100384Speter } 307100384Speter } else { 308100384Speter vm_offset_t addr = trunc_page(start); 309100384Speter rv = vm_map_find(map, 0, 0, 310100384Speter &addr, PAGE_SIZE, FALSE, prot, 311100384Speter VM_PROT_ALL, 0); 312100384Speter if (rv != KERN_SUCCESS) 313100384Speter return (EINVAL); 314100384Speter } 315100384Speter 316100384Speter if (fd != -1) { 317100384Speter struct pread_args r; 318107849Salfred r.fd = fd; 319107849Salfred r.buf = (void *) start; 320107849Salfred r.nbyte = end - start; 321107849Salfred r.offset = pos; 322100384Speter return (pread(td, &r)); 323100384Speter } else { 324100384Speter while (start < end) { 325100384Speter subyte((void *) start, 0); 326100384Speter start++; 327100384Speter } 328100384Speter return (0); 329100384Speter } 330100384Speter} 331114987Speter#endif 332100384Speter 333100384Speterint 334119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) 335100384Speter{ 336100384Speter struct mmap_args ap; 337107849Salfred vm_offset_t addr = (vm_offset_t) uap->addr; 338107849Salfred vm_size_t len = uap->len; 339107849Salfred int prot = uap->prot; 340107849Salfred int flags = uap->flags; 341107849Salfred int fd = uap->fd; 342107849Salfred off_t pos = (uap->poslo 343107849Salfred | ((off_t)uap->poshi << 32)); 344114987Speter#ifdef __ia64__ 345100384Speter vm_size_t pageoff; 346100384Speter int error; 347100384Speter 348100384Speter /* 349100384Speter * Attempt to handle page size hassles. 350100384Speter */ 351100384Speter pageoff = (pos & PAGE_MASK); 352100384Speter if (flags & MAP_FIXED) { 353100384Speter vm_offset_t start, end; 354100384Speter start = addr; 355100384Speter end = addr + len; 356100384Speter 357100384Speter if (start != trunc_page(start)) { 358119333Speter error = freebsd32_mmap_partial(td, start, 359119333Speter round_page(start), prot, 360119333Speter fd, pos); 361100384Speter if (fd != -1) 362100384Speter pos += round_page(start) - start; 363100384Speter start = round_page(start); 364100384Speter } 365100384Speter if (end != round_page(end)) { 366100384Speter vm_offset_t t = trunc_page(end); 367119333Speter error = freebsd32_mmap_partial(td, t, end, 368100384Speter prot, fd, 369100384Speter pos + t - start); 370100384Speter end = trunc_page(end); 371100384Speter } 372100384Speter if (end > start && fd != -1 && (pos & PAGE_MASK)) { 373100384Speter /* 374100384Speter * We can't map this region at all. The specified 375100384Speter * address doesn't have the same alignment as the file 376100384Speter * position. Fake the mapping by simply reading the 377100384Speter * entire region into memory. First we need to make 378100384Speter * sure the region exists. 379100384Speter */ 380100384Speter vm_map_t map; 381100384Speter struct pread_args r; 382100384Speter int rv; 383100384Speter 384100384Speter prot |= VM_PROT_WRITE; 385100384Speter map = &td->td_proc->p_vmspace->vm_map; 386100384Speter rv = vm_map_remove(map, start, end); 387100384Speter if (rv != KERN_SUCCESS) 388100384Speter return (EINVAL); 389100384Speter rv = vm_map_find(map, 0, 0, 390100384Speter &start, end - start, FALSE, 391100384Speter prot, VM_PROT_ALL, 0); 392100384Speter if (rv != KERN_SUCCESS) 393100384Speter return (EINVAL); 394107849Salfred r.fd = fd; 395107849Salfred r.buf = (void *) start; 396107849Salfred r.nbyte = end - start; 397107849Salfred r.offset = pos; 398100384Speter error = pread(td, &r); 399100384Speter if (error) 400100384Speter return (error); 401100384Speter 402100384Speter td->td_retval[0] = addr; 403100384Speter return (0); 404100384Speter } 405100384Speter if (end == start) { 406100384Speter /* 407100384Speter * After dealing with the ragged ends, there 408100384Speter * might be none left. 409100384Speter */ 410100384Speter td->td_retval[0] = addr; 411100384Speter return (0); 412100384Speter } 413100384Speter addr = start; 414100384Speter len = end - start; 415100384Speter } 416114987Speter#endif 417100384Speter 418107849Salfred ap.addr = (void *) addr; 419107849Salfred ap.len = len; 420107849Salfred ap.prot = prot; 421107849Salfred ap.flags = flags; 422107849Salfred ap.fd = fd; 423107849Salfred ap.pos = pos; 424100384Speter 425100384Speter return (mmap(td, &ap)); 426100384Speter} 427100384Speter 428100384Speterstruct itimerval32 { 429100384Speter struct timeval32 it_interval; 430100384Speter struct timeval32 it_value; 431100384Speter}; 432100384Speter 433121719SpeterCTASSERT(sizeof(struct itimerval32) == 16); 434121719Speter 435100384Speterint 436119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) 437100384Speter{ 438100384Speter int error; 439100384Speter caddr_t sg; 440100384Speter struct itimerval32 *p32, *op32, s32; 441100384Speter struct itimerval *p = NULL, *op = NULL, s; 442100384Speter 443107849Salfred p32 = uap->itv; 444100384Speter if (p32) { 445100384Speter sg = stackgap_init(); 446100384Speter p = stackgap_alloc(&sg, sizeof(struct itimerval)); 447107849Salfred uap->itv = (struct itimerval32 *)p; 448100384Speter error = copyin(p32, &s32, sizeof(s32)); 449100384Speter if (error) 450100384Speter return (error); 451100384Speter TV_CP(s32, s, it_interval); 452100384Speter TV_CP(s32, s, it_value); 453100384Speter error = copyout(&s, p, sizeof(s)); 454100384Speter if (error) 455100384Speter return (error); 456100384Speter } 457107849Salfred op32 = uap->oitv; 458100384Speter if (op32) { 459100384Speter sg = stackgap_init(); 460100384Speter op = stackgap_alloc(&sg, sizeof(struct itimerval)); 461107849Salfred uap->oitv = (struct itimerval32 *)op; 462100384Speter } 463100384Speter error = setitimer(td, (struct setitimer_args *) uap); 464100384Speter if (error) 465100384Speter return (error); 466100384Speter if (op32) { 467100384Speter error = copyin(op, &s, sizeof(s)); 468100384Speter if (error) 469100384Speter return (error); 470100384Speter TV_CP(s, s32, it_interval); 471100384Speter TV_CP(s, s32, it_value); 472100384Speter error = copyout(&s32, op32, sizeof(s32)); 473100384Speter } 474100384Speter return (error); 475100384Speter} 476100384Speter 477100384Speterint 478125171Speterfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap) 479125171Speter{ 480125171Speter int error; 481125171Speter caddr_t sg; 482125171Speter struct itimerval32 *p32, s32; 483125171Speter struct itimerval *p = NULL, s; 484125171Speter 485125171Speter p32 = uap->itv; 486125171Speter if (p32) { 487125171Speter sg = stackgap_init(); 488125171Speter p = stackgap_alloc(&sg, sizeof(struct itimerval)); 489125171Speter uap->itv = (struct itimerval32 *)p; 490125171Speter } 491125171Speter error = getitimer(td, (struct getitimer_args *) uap); 492125171Speter if (error) 493125171Speter return (error); 494125171Speter if (p32) { 495125171Speter error = copyin(p, &s, sizeof(s)); 496125171Speter if (error) 497125171Speter return (error); 498125171Speter TV_CP(s, s32, it_interval); 499125171Speter TV_CP(s, s32, it_value); 500125171Speter error = copyout(&s32, p32, sizeof(s32)); 501125171Speter } 502125171Speter return (error); 503125171Speter} 504125171Speter 505125171Speterint 506119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap) 507100384Speter{ 508100384Speter int error; 509100384Speter caddr_t sg; 510100384Speter struct timeval32 *p32, s32; 511100384Speter struct timeval *p = NULL, s; 512100384Speter 513107849Salfred p32 = uap->tv; 514100384Speter if (p32) { 515100384Speter sg = stackgap_init(); 516100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 517107849Salfred uap->tv = (struct timeval32 *)p; 518100384Speter error = copyin(p32, &s32, sizeof(s32)); 519100384Speter if (error) 520100384Speter return (error); 521100384Speter CP(s32, s, tv_sec); 522100384Speter CP(s32, s, tv_usec); 523100384Speter error = copyout(&s, p, sizeof(s)); 524100384Speter if (error) 525100384Speter return (error); 526100384Speter } 527100384Speter /* 528100384Speter * XXX big-endian needs to convert the fd_sets too. 529100384Speter */ 530100384Speter return (select(td, (struct select_args *) uap)); 531100384Speter} 532100384Speter 533114987Speterstruct kevent32 { 534114987Speter u_int32_t ident; /* identifier for this event */ 535114987Speter short filter; /* filter for event */ 536114987Speter u_short flags; 537114987Speter u_int fflags; 538114987Speter int32_t data; 539114987Speter u_int32_t udata; /* opaque user data identifier */ 540114987Speter}; 541114987Speter 542121719SpeterCTASSERT(sizeof(struct kevent32) == 20); 543121719Speter 544100384Speterint 545119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) 546114987Speter{ 547114987Speter int error; 548114987Speter caddr_t sg; 549114987Speter struct timespec32 ts32; 550114987Speter struct timespec ts; 551114987Speter struct kevent32 ks32; 552114987Speter struct kevent *ks; 553114987Speter struct kevent_args a; 554114987Speter int i; 555114987Speter 556114987Speter sg = stackgap_init(); 557114987Speter 558114987Speter a.fd = uap->fd; 559114987Speter a.changelist = uap->changelist; 560114987Speter a.nchanges = uap->nchanges; 561114987Speter a.eventlist = uap->eventlist; 562114987Speter a.nevents = uap->nevents; 563114987Speter a.timeout = NULL; 564114987Speter 565114987Speter if (uap->timeout) { 566114987Speter a.timeout = stackgap_alloc(&sg, sizeof(struct timespec)); 567114987Speter error = copyin(uap->timeout, &ts32, sizeof(ts32)); 568114987Speter if (error) 569114987Speter return (error); 570114987Speter CP(ts32, ts, tv_sec); 571114987Speter CP(ts32, ts, tv_nsec); 572114987Speter error = copyout(&ts, (void *)(uintptr_t)a.timeout, sizeof(ts)); 573114987Speter if (error) 574114987Speter return (error); 575114987Speter } 576114987Speter if (uap->changelist) { 577119333Speter a.changelist = (struct kevent *)stackgap_alloc(&sg, 578119333Speter uap->nchanges * sizeof(struct kevent)); 579114987Speter for (i = 0; i < uap->nchanges; i++) { 580119333Speter error = copyin(&uap->changelist[i], &ks32, 581119333Speter sizeof(ks32)); 582114987Speter if (error) 583114987Speter return (error); 584114987Speter ks = (struct kevent *)(uintptr_t)&a.changelist[i]; 585114987Speter CP(ks32, *ks, ident); 586114987Speter CP(ks32, *ks, filter); 587114987Speter CP(ks32, *ks, flags); 588114987Speter CP(ks32, *ks, fflags); 589114987Speter CP(ks32, *ks, data); 590114987Speter PTRIN_CP(ks32, *ks, udata); 591114987Speter } 592114987Speter } 593114987Speter if (uap->eventlist) { 594119333Speter a.eventlist = stackgap_alloc(&sg, 595119333Speter uap->nevents * sizeof(struct kevent)); 596114987Speter } 597114987Speter error = kevent(td, &a); 598114987Speter if (uap->eventlist && error > 0) { 599114987Speter for (i = 0; i < error; i++) { 600114987Speter ks = &a.eventlist[i]; 601114987Speter CP(*ks, ks32, ident); 602114987Speter CP(*ks, ks32, filter); 603114987Speter CP(*ks, ks32, flags); 604114987Speter CP(*ks, ks32, fflags); 605114987Speter CP(*ks, ks32, data); 606114987Speter PTROUT_CP(*ks, ks32, udata); 607119333Speter error = copyout(&ks32, &uap->eventlist[i], 608119333Speter sizeof(ks32)); 609114987Speter if (error) 610114987Speter return (error); 611114987Speter } 612114987Speter } 613114987Speter return error; 614114987Speter} 615114987Speter 616114987Speterint 617119333Speterfreebsd32_gettimeofday(struct thread *td, 618119333Speter struct freebsd32_gettimeofday_args *uap) 619100384Speter{ 620123425Speter struct timeval atv; 621123425Speter struct timeval32 atv32; 622123425Speter struct timezone rtz; 623123425Speter int error = 0; 624100384Speter 625123425Speter if (uap->tp) { 626123425Speter microtime(&atv); 627123425Speter CP(atv, atv32, tv_sec); 628123425Speter CP(atv, atv32, tv_usec); 629123425Speter error = copyout(&atv32, uap->tp, sizeof (atv32)); 630100384Speter } 631123425Speter if (error == 0 && uap->tzp != NULL) { 632123425Speter rtz.tz_minuteswest = tz_minuteswest; 633123425Speter rtz.tz_dsttime = tz_dsttime; 634123425Speter error = copyout(&rtz, uap->tzp, sizeof (rtz)); 635100384Speter } 636100384Speter return (error); 637100384Speter} 638100384Speter 639100384Speterint 640119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) 641100384Speter{ 642100384Speter int error; 643100384Speter caddr_t sg; 644100384Speter struct rusage32 *p32, s32; 645100384Speter struct rusage *p = NULL, s; 646100384Speter 647107849Salfred p32 = uap->rusage; 648100384Speter if (p32) { 649100384Speter sg = stackgap_init(); 650100384Speter p = stackgap_alloc(&sg, sizeof(struct rusage)); 651107849Salfred uap->rusage = (struct rusage32 *)p; 652100384Speter } 653100384Speter error = getrusage(td, (struct getrusage_args *) uap); 654100384Speter if (error) 655100384Speter return (error); 656100384Speter if (p32) { 657100384Speter error = copyin(p, &s, sizeof(s)); 658100384Speter if (error) 659100384Speter return (error); 660100384Speter TV_CP(s, s32, ru_utime); 661100384Speter TV_CP(s, s32, ru_stime); 662100384Speter CP(s, s32, ru_maxrss); 663100384Speter CP(s, s32, ru_ixrss); 664100384Speter CP(s, s32, ru_idrss); 665100384Speter CP(s, s32, ru_isrss); 666100384Speter CP(s, s32, ru_minflt); 667100384Speter CP(s, s32, ru_majflt); 668100384Speter CP(s, s32, ru_nswap); 669100384Speter CP(s, s32, ru_inblock); 670100384Speter CP(s, s32, ru_oublock); 671100384Speter CP(s, s32, ru_msgsnd); 672100384Speter CP(s, s32, ru_msgrcv); 673100384Speter CP(s, s32, ru_nsignals); 674100384Speter CP(s, s32, ru_nvcsw); 675100384Speter CP(s, s32, ru_nivcsw); 676100384Speter error = copyout(&s32, p32, sizeof(s32)); 677100384Speter } 678100384Speter return (error); 679100384Speter} 680100384Speter 681100384Speterstruct iovec32 { 682100384Speter u_int32_t iov_base; 683100384Speter int iov_len; 684100384Speter}; 685100384Speter#define STACKGAPLEN 400 686100384Speter 687121719SpeterCTASSERT(sizeof(struct iovec32) == 8); 688121719Speter 689100384Speterint 690119333Speterfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) 691100384Speter{ 692100384Speter int error, osize, nsize, i; 693100384Speter caddr_t sg; 694100384Speter struct readv_args /* { 695100384Speter syscallarg(int) fd; 696100384Speter syscallarg(struct iovec *) iovp; 697100384Speter syscallarg(u_int) iovcnt; 698100384Speter } */ a; 699100384Speter struct iovec32 *oio; 700100384Speter struct iovec *nio; 701100384Speter 702100384Speter sg = stackgap_init(); 703100384Speter 704107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 705100384Speter return (EINVAL); 706100384Speter 707107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 708107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 709100384Speter 710111119Simp oio = malloc(osize, M_TEMP, M_WAITOK); 711111119Simp nio = malloc(nsize, M_TEMP, M_WAITOK); 712100384Speter 713100384Speter error = 0; 714107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 715100384Speter goto punt; 716107849Salfred for (i = 0; i < uap->iovcnt; i++) { 717100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 718100384Speter nio[i].iov_len = oio[i].iov_len; 719100384Speter } 720100384Speter 721107849Salfred a.fd = uap->fd; 722107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 723107849Salfred a.iovcnt = uap->iovcnt; 724100384Speter 725107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 726100384Speter goto punt; 727100384Speter error = readv(td, &a); 728100384Speter 729100384Speterpunt: 730100384Speter free(oio, M_TEMP); 731100384Speter free(nio, M_TEMP); 732100384Speter return (error); 733100384Speter} 734100384Speter 735100384Speterint 736119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) 737100384Speter{ 738100384Speter int error, i, nsize, osize; 739100384Speter caddr_t sg; 740100384Speter struct writev_args /* { 741100384Speter syscallarg(int) fd; 742100384Speter syscallarg(struct iovec *) iovp; 743100384Speter syscallarg(u_int) iovcnt; 744100384Speter } */ a; 745100384Speter struct iovec32 *oio; 746100384Speter struct iovec *nio; 747100384Speter 748100384Speter sg = stackgap_init(); 749100384Speter 750107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 751100384Speter return (EINVAL); 752100384Speter 753107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 754107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 755100384Speter 756111119Simp oio = malloc(osize, M_TEMP, M_WAITOK); 757111119Simp nio = malloc(nsize, M_TEMP, M_WAITOK); 758100384Speter 759100384Speter error = 0; 760107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 761100384Speter goto punt; 762107849Salfred for (i = 0; i < uap->iovcnt; i++) { 763100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 764100384Speter nio[i].iov_len = oio[i].iov_len; 765100384Speter } 766100384Speter 767107849Salfred a.fd = uap->fd; 768107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 769107849Salfred a.iovcnt = uap->iovcnt; 770100384Speter 771107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 772100384Speter goto punt; 773100384Speter error = writev(td, &a); 774100384Speter 775100384Speterpunt: 776100384Speter free(oio, M_TEMP); 777100384Speter free(nio, M_TEMP); 778100384Speter return (error); 779100384Speter} 780100384Speter 781100384Speterint 782119333Speterfreebsd32_settimeofday(struct thread *td, 783119333Speter struct freebsd32_settimeofday_args *uap) 784100384Speter{ 785100384Speter int error; 786100384Speter caddr_t sg; 787100384Speter struct timeval32 *p32, s32; 788100384Speter struct timeval *p = NULL, s; 789100384Speter 790107849Salfred p32 = uap->tv; 791100384Speter if (p32) { 792100384Speter sg = stackgap_init(); 793100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 794107849Salfred uap->tv = (struct timeval32 *)p; 795100384Speter error = copyin(p32, &s32, sizeof(s32)); 796100384Speter if (error) 797100384Speter return (error); 798100384Speter CP(s32, s, tv_sec); 799100384Speter CP(s32, s, tv_usec); 800100384Speter error = copyout(&s, p, sizeof(s)); 801100384Speter if (error) 802100384Speter return (error); 803100384Speter } 804100384Speter return (settimeofday(td, (struct settimeofday_args *) uap)); 805100384Speter} 806100384Speter 807100384Speterint 808119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) 809100384Speter{ 810100384Speter int error; 811100384Speter caddr_t sg; 812100384Speter struct timeval32 *p32, s32[2]; 813100384Speter struct timeval *p = NULL, s[2]; 814100384Speter 815107849Salfred p32 = uap->tptr; 816100384Speter if (p32) { 817100384Speter sg = stackgap_init(); 818100384Speter p = stackgap_alloc(&sg, 2*sizeof(struct timeval)); 819107849Salfred uap->tptr = (struct timeval32 *)p; 820100384Speter error = copyin(p32, s32, sizeof(s32)); 821100384Speter if (error) 822100384Speter return (error); 823100384Speter CP(s32[0], s[0], tv_sec); 824100384Speter CP(s32[0], s[0], tv_usec); 825100384Speter CP(s32[1], s[1], tv_sec); 826100384Speter CP(s32[1], s[1], tv_usec); 827100384Speter error = copyout(s, p, sizeof(s)); 828100384Speter if (error) 829100384Speter return (error); 830100384Speter } 831100384Speter return (utimes(td, (struct utimes_args *) uap)); 832100384Speter} 833100384Speter 834100384Speterint 835119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) 836100384Speter{ 837100384Speter int error; 838100384Speter caddr_t sg; 839100384Speter struct timeval32 *p32, *op32, s32; 840100384Speter struct timeval *p = NULL, *op = NULL, s; 841100384Speter 842107849Salfred p32 = uap->delta; 843100384Speter if (p32) { 844100384Speter sg = stackgap_init(); 845100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 846107849Salfred uap->delta = (struct timeval32 *)p; 847100384Speter error = copyin(p32, &s32, sizeof(s32)); 848100384Speter if (error) 849100384Speter return (error); 850100384Speter CP(s32, s, tv_sec); 851100384Speter CP(s32, s, tv_usec); 852100384Speter error = copyout(&s, p, sizeof(s)); 853100384Speter if (error) 854100384Speter return (error); 855100384Speter } 856107849Salfred op32 = uap->olddelta; 857100384Speter if (op32) { 858100384Speter sg = stackgap_init(); 859100384Speter op = stackgap_alloc(&sg, sizeof(struct timeval)); 860107849Salfred uap->olddelta = (struct timeval32 *)op; 861100384Speter } 862100384Speter error = utimes(td, (struct utimes_args *) uap); 863100384Speter if (error) 864100384Speter return error; 865100384Speter if (op32) { 866100384Speter error = copyin(op, &s, sizeof(s)); 867100384Speter if (error) 868100384Speter return (error); 869100384Speter CP(s, s32, tv_sec); 870100384Speter CP(s, s32, tv_usec); 871100384Speter error = copyout(&s32, op32, sizeof(s32)); 872100384Speter } 873100384Speter return (error); 874100384Speter} 875100384Speter 876100384Speterint 877119333Speterfreebsd32_statfs(struct thread *td, struct freebsd32_statfs_args *uap) 878100384Speter{ 879100384Speter int error; 880100384Speter caddr_t sg; 881100384Speter struct statfs32 *p32, s32; 882100384Speter struct statfs *p = NULL, s; 883100384Speter 884107849Salfred p32 = uap->buf; 885100384Speter if (p32) { 886100384Speter sg = stackgap_init(); 887100384Speter p = stackgap_alloc(&sg, sizeof(struct statfs)); 888107849Salfred uap->buf = (struct statfs32 *)p; 889100384Speter } 890100384Speter error = statfs(td, (struct statfs_args *) uap); 891100384Speter if (error) 892100384Speter return (error); 893100384Speter if (p32) { 894100384Speter error = copyin(p, &s, sizeof(s)); 895100384Speter if (error) 896100384Speter return (error); 897100384Speter copy_statfs(&s, &s32); 898100384Speter error = copyout(&s32, p32, sizeof(s32)); 899100384Speter } 900100384Speter return (error); 901100384Speter} 902100384Speter 903100384Speterint 904119333Speterfreebsd32_fstatfs(struct thread *td, struct freebsd32_fstatfs_args *uap) 905100384Speter{ 906100384Speter int error; 907100384Speter caddr_t sg; 908100384Speter struct statfs32 *p32, s32; 909100384Speter struct statfs *p = NULL, s; 910100384Speter 911107849Salfred p32 = uap->buf; 912100384Speter if (p32) { 913100384Speter sg = stackgap_init(); 914100384Speter p = stackgap_alloc(&sg, sizeof(struct statfs)); 915107849Salfred uap->buf = (struct statfs32 *)p; 916100384Speter } 917100384Speter error = fstatfs(td, (struct fstatfs_args *) uap); 918100384Speter if (error) 919100384Speter return (error); 920100384Speter if (p32) { 921100384Speter error = copyin(p, &s, sizeof(s)); 922100384Speter if (error) 923100384Speter return (error); 924100384Speter copy_statfs(&s, &s32); 925100384Speter error = copyout(&s32, p32, sizeof(s32)); 926100384Speter } 927100384Speter return (error); 928100384Speter} 929100384Speter 930100384Speterint 931119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) 932100384Speter{ 933100384Speter /* 934100384Speter * Vector through to semsys if it is loaded. 935100384Speter */ 936100384Speter return sysent[169].sy_call(td, uap); 937100384Speter} 938100384Speter 939100384Speterint 940119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap) 941100384Speter{ 942100384Speter /* 943100384Speter * Vector through to msgsys if it is loaded. 944100384Speter */ 945100384Speter return sysent[170].sy_call(td, uap); 946100384Speter} 947100384Speter 948100384Speterint 949119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap) 950100384Speter{ 951100384Speter /* 952100384Speter * Vector through to shmsys if it is loaded. 953100384Speter */ 954100384Speter return sysent[171].sy_call(td, uap); 955100384Speter} 956100384Speter 957100384Speterint 958119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) 959100384Speter{ 960100384Speter struct pread_args ap; 961100384Speter 962107849Salfred ap.fd = uap->fd; 963107849Salfred ap.buf = uap->buf; 964107849Salfred ap.nbyte = uap->nbyte; 965119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 966100384Speter return (pread(td, &ap)); 967100384Speter} 968100384Speter 969100384Speterint 970119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) 971100384Speter{ 972100384Speter struct pwrite_args ap; 973100384Speter 974107849Salfred ap.fd = uap->fd; 975107849Salfred ap.buf = uap->buf; 976107849Salfred ap.nbyte = uap->nbyte; 977119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 978100384Speter return (pwrite(td, &ap)); 979100384Speter} 980100384Speter 981100384Speterint 982119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) 983100384Speter{ 984100384Speter int error; 985100384Speter struct lseek_args ap; 986100384Speter off_t pos; 987100384Speter 988107849Salfred ap.fd = uap->fd; 989119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 990107849Salfred ap.whence = uap->whence; 991100384Speter error = lseek(td, &ap); 992100384Speter /* Expand the quad return into two parts for eax and edx */ 993100384Speter pos = *(off_t *)(td->td_retval); 994100384Speter td->td_retval[0] = pos & 0xffffffff; /* %eax */ 995100384Speter td->td_retval[1] = pos >> 32; /* %edx */ 996100384Speter return error; 997100384Speter} 998100384Speter 999100384Speterint 1000119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) 1001100384Speter{ 1002100384Speter struct truncate_args ap; 1003100384Speter 1004107849Salfred ap.path = uap->path; 1005119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1006100384Speter return (truncate(td, &ap)); 1007100384Speter} 1008100384Speter 1009100384Speterint 1010119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 1011100384Speter{ 1012100384Speter struct ftruncate_args ap; 1013100384Speter 1014107849Salfred ap.fd = uap->fd; 1015119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1016100384Speter return (ftruncate(td, &ap)); 1017100384Speter} 1018100384Speter 1019104738Speter#ifdef COMPAT_FREEBSD4 1020100384Speterint 1021119333Speterfreebsd4_freebsd32_sendfile(struct thread *td, 1022119333Speter struct freebsd4_freebsd32_sendfile_args *uap) 1023104738Speter{ 1024104738Speter struct freebsd4_sendfile_args ap; 1025104738Speter 1026107849Salfred ap.fd = uap->fd; 1027107849Salfred ap.s = uap->s; 1028119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1029107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1030107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1031107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1032107849Salfred ap.flags = uap->flags; 1033104738Speter return (freebsd4_sendfile(td, &ap)); 1034104738Speter} 1035104738Speter#endif 1036104738Speter 1037104738Speterint 1038119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) 1039100384Speter{ 1040100384Speter struct sendfile_args ap; 1041100384Speter 1042107849Salfred ap.fd = uap->fd; 1043107849Salfred ap.s = uap->s; 1044119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1045107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1046107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1047107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1048107849Salfred ap.flags = uap->flags; 1049100384Speter return (sendfile(td, &ap)); 1050100384Speter} 1051100384Speter 1052100384Speterstruct stat32 { 1053100384Speter udev_t st_dev; 1054100384Speter ino_t st_ino; 1055100384Speter mode_t st_mode; 1056100384Speter nlink_t st_nlink; 1057100384Speter uid_t st_uid; 1058100384Speter gid_t st_gid; 1059100384Speter udev_t st_rdev; 1060100384Speter struct timespec32 st_atimespec; 1061100384Speter struct timespec32 st_mtimespec; 1062100384Speter struct timespec32 st_ctimespec; 1063100384Speter off_t st_size; 1064100384Speter int64_t st_blocks; 1065100384Speter u_int32_t st_blksize; 1066100384Speter u_int32_t st_flags; 1067100384Speter u_int32_t st_gen; 1068121719Speter struct timespec32 st_birthtimespec; 1069121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1070121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1071100384Speter}; 1072100384Speter 1073121719Speter 1074121719SpeterCTASSERT(sizeof(struct stat32) == 96); 1075121719Speter 1076100384Speterstatic void 1077100384Spetercopy_stat( struct stat *in, struct stat32 *out) 1078100384Speter{ 1079100384Speter CP(*in, *out, st_dev); 1080100384Speter CP(*in, *out, st_ino); 1081100384Speter CP(*in, *out, st_mode); 1082100384Speter CP(*in, *out, st_nlink); 1083100384Speter CP(*in, *out, st_uid); 1084100384Speter CP(*in, *out, st_gid); 1085100384Speter CP(*in, *out, st_rdev); 1086100384Speter TS_CP(*in, *out, st_atimespec); 1087100384Speter TS_CP(*in, *out, st_mtimespec); 1088100384Speter TS_CP(*in, *out, st_ctimespec); 1089100384Speter CP(*in, *out, st_size); 1090100384Speter CP(*in, *out, st_blocks); 1091100384Speter CP(*in, *out, st_blksize); 1092100384Speter CP(*in, *out, st_flags); 1093100384Speter CP(*in, *out, st_gen); 1094100384Speter} 1095100384Speter 1096100384Speterint 1097119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) 1098100384Speter{ 1099123746Speter struct stat sb; 1100123746Speter struct stat32 sb32; 1101100384Speter int error; 1102123746Speter struct nameidata nd; 1103100384Speter 1104123746Speter#ifdef LOOKUP_SHARED 1105123746Speter NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | NOOBJ, 1106123746Speter UIO_USERSPACE, uap->path, td); 1107123746Speter#else 1108123746Speter NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1109123746Speter uap->path, td); 1110123746Speter#endif 1111123746Speter if ((error = namei(&nd)) != 0) 1112123746Speter return (error); 1113123746Speter error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td); 1114123746Speter NDFREE(&nd, NDF_ONLY_PNBUF); 1115123746Speter vput(nd.ni_vp); 1116100384Speter if (error) 1117100384Speter return (error); 1118123746Speter copy_stat(&sb, &sb32); 1119123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1120100384Speter return (error); 1121100384Speter} 1122100384Speter 1123100384Speterint 1124119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) 1125100384Speter{ 1126123746Speter struct file *fp; 1127123746Speter struct stat ub; 1128123746Speter struct stat32 ub32; 1129100384Speter int error; 1130100384Speter 1131123746Speter if ((error = fget(td, uap->fd, &fp)) != 0) 1132123746Speter return (error); 1133123746Speter mtx_lock(&Giant); 1134123746Speter error = fo_stat(fp, &ub, td->td_ucred, td); 1135123746Speter mtx_unlock(&Giant); 1136123746Speter fdrop(fp, td); 1137100384Speter if (error) 1138100384Speter return (error); 1139123746Speter copy_stat(&ub, &ub32); 1140123746Speter error = copyout(&ub32, uap->ub, sizeof(ub32)); 1141100384Speter return (error); 1142100384Speter} 1143100384Speter 1144100384Speterint 1145119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) 1146100384Speter{ 1147100384Speter int error; 1148123746Speter struct vnode *vp; 1149123746Speter struct stat sb; 1150123746Speter struct stat32 sb32; 1151123746Speter struct nameidata nd; 1152100384Speter 1153123746Speter NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1154123746Speter uap->path, td); 1155123746Speter if ((error = namei(&nd)) != 0) 1156123746Speter return (error); 1157123746Speter vp = nd.ni_vp; 1158123746Speter error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td); 1159123746Speter NDFREE(&nd, NDF_ONLY_PNBUF); 1160123746Speter vput(vp); 1161100384Speter if (error) 1162100384Speter return (error); 1163123746Speter copy_stat(&sb, &sb32); 1164123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1165100384Speter return (error); 1166100384Speter} 1167100384Speter 1168100384Speter/* 1169100384Speter * MPSAFE 1170100384Speter */ 1171100384Speterint 1172119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) 1173100384Speter{ 1174100384Speter int error, name[CTL_MAXNAME]; 1175100384Speter size_t j, oldlen; 1176100384Speter 1177100384Speter if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1178100384Speter return (EINVAL); 1179100384Speter 1180100384Speter error = copyin(uap->name, &name, uap->namelen * sizeof(int)); 1181100384Speter if (error) 1182100384Speter return (error); 1183100384Speter 1184100384Speter mtx_lock(&Giant); 1185100384Speter 1186100384Speter if (uap->oldlenp) 1187100384Speter oldlen = fuword32(uap->oldlenp); 1188100384Speter else 1189100384Speter oldlen = 0; 1190100384Speter error = userland_sysctl(td, name, uap->namelen, 1191100384Speter uap->old, &oldlen, 1, 1192100384Speter uap->new, uap->newlen, &j); 1193100384Speter if (error && error != ENOMEM) 1194100384Speter goto done2; 1195100384Speter if (uap->oldlenp) { 1196100384Speter suword32(uap->oldlenp, j); 1197100384Speter } 1198100384Speterdone2: 1199100384Speter mtx_unlock(&Giant); 1200100384Speter return (error); 1201100384Speter} 1202100384Speter 1203100384Speterstruct sigaction32 { 1204100384Speter u_int32_t sa_u; 1205100384Speter int sa_flags; 1206100384Speter sigset_t sa_mask; 1207100384Speter}; 1208100384Speter 1209121719SpeterCTASSERT(sizeof(struct sigaction32) == 24); 1210121719Speter 1211100384Speterint 1212119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) 1213100384Speter{ 1214113859Sjhb struct sigaction32 s32; 1215113859Sjhb struct sigaction sa, osa, *sap; 1216100384Speter int error; 1217100384Speter 1218113859Sjhb if (uap->act) { 1219113859Sjhb error = copyin(uap->act, &s32, sizeof(s32)); 1220100384Speter if (error) 1221100384Speter return (error); 1222113859Sjhb sa.sa_handler = PTRIN(s32.sa_u); 1223113859Sjhb CP(s32, sa, sa_flags); 1224113859Sjhb CP(s32, sa, sa_mask); 1225113859Sjhb sap = &sa; 1226113859Sjhb } else 1227113859Sjhb sap = NULL; 1228113859Sjhb error = kern_sigaction(td, uap->sig, sap, &osa, 0); 1229113859Sjhb if (error != 0 && uap->oact != NULL) { 1230113859Sjhb s32.sa_u = PTROUT(osa.sa_handler); 1231113859Sjhb CP(osa, s32, sa_flags); 1232113859Sjhb CP(osa, s32, sa_mask); 1233113859Sjhb error = copyout(&s32, uap->oact, sizeof(s32)); 1234100384Speter } 1235100384Speter return (error); 1236100384Speter} 1237100384Speter 1238114987Speter#ifdef COMPAT_FREEBSD4 1239114987Speterint 1240119333Speterfreebsd4_freebsd32_sigaction(struct thread *td, 1241119333Speter struct freebsd4_freebsd32_sigaction_args *uap) 1242114987Speter{ 1243114987Speter struct sigaction32 s32; 1244114987Speter struct sigaction sa, osa, *sap; 1245114987Speter int error; 1246114987Speter 1247114987Speter if (uap->act) { 1248114987Speter error = copyin(uap->act, &s32, sizeof(s32)); 1249114987Speter if (error) 1250114987Speter return (error); 1251114987Speter sa.sa_handler = PTRIN(s32.sa_u); 1252114987Speter CP(s32, sa, sa_flags); 1253114987Speter CP(s32, sa, sa_mask); 1254114987Speter sap = &sa; 1255114987Speter } else 1256114987Speter sap = NULL; 1257114987Speter error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 1258114987Speter if (error != 0 && uap->oact != NULL) { 1259114987Speter s32.sa_u = PTROUT(osa.sa_handler); 1260114987Speter CP(osa, s32, sa_flags); 1261114987Speter CP(osa, s32, sa_mask); 1262114987Speter error = copyout(&s32, uap->oact, sizeof(s32)); 1263114987Speter } 1264114987Speter return (error); 1265114987Speter} 1266114987Speter#endif 1267114987Speter 1268100384Speter#if 0 1269100384Speter 1270100384Speterint 1271119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) 1272100384Speter{ 1273100384Speter int error; 1274100384Speter caddr_t sg; 1275100384Speter struct yyy32 *p32, s32; 1276100384Speter struct yyy *p = NULL, s; 1277100384Speter 1278107849Salfred p32 = uap->zzz; 1279100384Speter if (p32) { 1280100384Speter sg = stackgap_init(); 1281100384Speter p = stackgap_alloc(&sg, sizeof(struct yyy)); 1282107849Salfred uap->zzz = (struct yyy32 *)p; 1283100384Speter error = copyin(p32, &s32, sizeof(s32)); 1284100384Speter if (error) 1285100384Speter return (error); 1286100384Speter /* translate in */ 1287100384Speter error = copyout(&s, p, sizeof(s)); 1288100384Speter if (error) 1289100384Speter return (error); 1290100384Speter } 1291100384Speter error = xxx(td, (struct xxx_args *) uap); 1292100384Speter if (error) 1293100384Speter return (error); 1294100384Speter if (p32) { 1295100384Speter error = copyin(p, &s, sizeof(s)); 1296100384Speter if (error) 1297100384Speter return (error); 1298100384Speter /* translate out */ 1299100384Speter error = copyout(&s32, p32, sizeof(s32)); 1300100384Speter } 1301100384Speter return (error); 1302100384Speter} 1303100384Speter 1304100384Speter#endif 1305