freebsd32_misc.c revision 244172
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: stable/9/sys/compat/freebsd32/freebsd32_misc.c 244172 2012-12-13 06:17:05Z kib $"); 29118031Sobrien 30104738Speter#include "opt_compat.h" 31191673Sjamie#include "opt_inet.h" 32191673Sjamie#include "opt_inet6.h" 33104738Speter 34205014Snwhitehorn#define __ELF_WORD_SIZE 32 35205014Snwhitehorn 36100384Speter#include <sys/param.h> 37100384Speter#include <sys/bus.h> 38162954Sphk#include <sys/clock.h> 39100384Speter#include <sys/exec.h> 40100384Speter#include <sys/fcntl.h> 41100384Speter#include <sys/filedesc.h> 42100384Speter#include <sys/imgact.h> 43185435Sbz#include <sys/jail.h> 44100384Speter#include <sys/kernel.h> 45161343Sjkim#include <sys/limits.h> 46220158Skib#include <sys/linker.h> 47100384Speter#include <sys/lock.h> 48100384Speter#include <sys/malloc.h> 49100384Speter#include <sys/file.h> /* Must come after sys/malloc.h */ 50205014Snwhitehorn#include <sys/imgact.h> 51151909Sps#include <sys/mbuf.h> 52100384Speter#include <sys/mman.h> 53100384Speter#include <sys/module.h> 54100384Speter#include <sys/mount.h> 55100384Speter#include <sys/mutex.h> 56183044Sobrien#include <sys/namei.h> 57100384Speter#include <sys/proc.h> 58100384Speter#include <sys/reboot.h> 59100384Speter#include <sys/resource.h> 60100384Speter#include <sys/resourcevar.h> 61100384Speter#include <sys/selinfo.h> 62146950Sps#include <sys/eventvar.h> /* Must come after sys/selinfo.h */ 63100384Speter#include <sys/pipe.h> /* Must come after sys/selinfo.h */ 64100384Speter#include <sys/signal.h> 65100384Speter#include <sys/signalvar.h> 66100384Speter#include <sys/socket.h> 67100384Speter#include <sys/socketvar.h> 68100384Speter#include <sys/stat.h> 69150883Sjhb#include <sys/syscall.h> 70113859Sjhb#include <sys/syscallsubr.h> 71100384Speter#include <sys/sysctl.h> 72100384Speter#include <sys/sysent.h> 73100384Speter#include <sys/sysproto.h> 74183044Sobrien#include <sys/systm.h> 75162551Sdavidxu#include <sys/thr.h> 76100384Speter#include <sys/unistd.h> 77162551Sdavidxu#include <sys/ucontext.h> 78100384Speter#include <sys/vnode.h> 79127140Sjhb#include <sys/wait.h> 80157285Sps#include <sys/ipc.h> 81174381Sjhb#include <sys/msg.h> 82174381Sjhb#include <sys/sem.h> 83157285Sps#include <sys/shm.h> 84100384Speter 85191673Sjamie#ifdef INET 86191673Sjamie#include <netinet/in.h> 87191673Sjamie#endif 88191673Sjamie 89100384Speter#include <vm/vm.h> 90100384Speter#include <vm/vm_param.h> 91100384Speter#include <vm/pmap.h> 92100384Speter#include <vm/vm_map.h> 93100384Speter#include <vm/vm_object.h> 94100384Speter#include <vm/vm_extern.h> 95100384Speter 96151582Sps#include <machine/cpu.h> 97205014Snwhitehorn#include <machine/elf.h> 98151582Sps 99183188Sobrien#include <security/audit/audit.h> 100183188Sobrien 101119333Speter#include <compat/freebsd32/freebsd32_util.h> 102119333Speter#include <compat/freebsd32/freebsd32.h> 103174380Sjhb#include <compat/freebsd32/freebsd32_ipc.h> 104163018Sdavidxu#include <compat/freebsd32/freebsd32_signal.h> 105119333Speter#include <compat/freebsd32/freebsd32_proto.h> 106100384Speter 107121719SpeterCTASSERT(sizeof(struct timeval32) == 8); 108121719SpeterCTASSERT(sizeof(struct timespec32) == 8); 109174377SjhbCTASSERT(sizeof(struct itimerval32) == 16); 110121719SpeterCTASSERT(sizeof(struct statfs32) == 256); 111121719SpeterCTASSERT(sizeof(struct rusage32) == 72); 112174377SjhbCTASSERT(sizeof(struct sigaltstack32) == 12); 113174377SjhbCTASSERT(sizeof(struct kevent32) == 20); 114174377SjhbCTASSERT(sizeof(struct iovec32) == 8); 115174377SjhbCTASSERT(sizeof(struct msghdr32) == 28); 116174377SjhbCTASSERT(sizeof(struct stat32) == 96); 117174377SjhbCTASSERT(sizeof(struct sigaction32) == 24); 118121719Speter 119174377Sjhbstatic int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count); 120174377Sjhbstatic int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count); 121174377Sjhb 122205014Snwhitehorn#if BYTE_ORDER == BIG_ENDIAN 123205014Snwhitehorn#define PAIR32TO64(type, name) ((name ## 2) | ((type)(name ## 1) << 32)) 124205014Snwhitehorn#define RETVAL_HI 0 125205014Snwhitehorn#define RETVAL_LO 1 126205014Snwhitehorn#else 127205014Snwhitehorn#define PAIR32TO64(type, name) ((name ## 1) | ((type)(name ## 2) << 32)) 128205014Snwhitehorn#define RETVAL_HI 1 129205014Snwhitehorn#define RETVAL_LO 0 130205014Snwhitehorn#endif 131205014Snwhitehorn 132207007Skibvoid 133207007Skibfreebsd32_rusage_out(const struct rusage *s, struct rusage32 *s32) 134207007Skib{ 135207007Skib 136207007Skib TV_CP(*s, *s32, ru_utime); 137207007Skib TV_CP(*s, *s32, ru_stime); 138207007Skib CP(*s, *s32, ru_maxrss); 139207007Skib CP(*s, *s32, ru_ixrss); 140207007Skib CP(*s, *s32, ru_idrss); 141207007Skib CP(*s, *s32, ru_isrss); 142207007Skib CP(*s, *s32, ru_minflt); 143207007Skib CP(*s, *s32, ru_majflt); 144207007Skib CP(*s, *s32, ru_nswap); 145207007Skib CP(*s, *s32, ru_inblock); 146207007Skib CP(*s, *s32, ru_oublock); 147207007Skib CP(*s, *s32, ru_msgsnd); 148207007Skib CP(*s, *s32, ru_msgrcv); 149207007Skib CP(*s, *s32, ru_nsignals); 150207007Skib CP(*s, *s32, ru_nvcsw); 151207007Skib CP(*s, *s32, ru_nivcsw); 152207007Skib} 153207007Skib 154100384Speterint 155119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) 156100384Speter{ 157127140Sjhb int error, status; 158127140Sjhb struct rusage32 ru32; 159136152Sjhb struct rusage ru, *rup; 160100384Speter 161136152Sjhb if (uap->rusage != NULL) 162136152Sjhb rup = &ru; 163136152Sjhb else 164136152Sjhb rup = NULL; 165136152Sjhb error = kern_wait(td, uap->pid, &status, uap->options, rup); 166100384Speter if (error) 167100384Speter return (error); 168127140Sjhb if (uap->status != NULL) 169127140Sjhb error = copyout(&status, uap->status, sizeof(status)); 170127140Sjhb if (uap->rusage != NULL && error == 0) { 171207007Skib freebsd32_rusage_out(&ru, &ru32); 172127140Sjhb error = copyout(&ru32, uap->rusage, sizeof(ru32)); 173100384Speter } 174100384Speter return (error); 175100384Speter} 176100384Speter 177244172Skibint 178244172Skibfreebsd32_wait6(struct thread *td, struct freebsd32_wait6_args *uap) 179244172Skib{ 180244172Skib struct wrusage32 wru32; 181244172Skib struct __wrusage wru, *wrup; 182244172Skib struct siginfo32 si32; 183244172Skib struct __siginfo si, *sip; 184244172Skib int error, status; 185244172Skib 186244172Skib if (uap->wrusage != NULL) 187244172Skib wrup = &wru; 188244172Skib else 189244172Skib wrup = NULL; 190244172Skib if (uap->info != NULL) { 191244172Skib sip = &si; 192244172Skib bzero(sip, sizeof(*sip)); 193244172Skib } else 194244172Skib sip = NULL; 195244172Skib error = kern_wait6(td, uap->idtype, uap->id, &status, uap->options, 196244172Skib wrup, sip); 197244172Skib if (error != 0) 198244172Skib return (error); 199244172Skib if (uap->status != NULL) 200244172Skib error = copyout(&status, uap->status, sizeof(status)); 201244172Skib if (uap->wrusage != NULL && error == 0) { 202244172Skib freebsd32_rusage_out(&wru.wru_self, &wru32.wru_self); 203244172Skib freebsd32_rusage_out(&wru.wru_children, &wru32.wru_children); 204244172Skib error = copyout(&wru32, uap->wrusage, sizeof(wru32)); 205244172Skib } 206244172Skib if (uap->info != NULL && error == 0) { 207244172Skib siginfo_to_siginfo32 (&si, &si32); 208244172Skib error = copyout(&si32, uap->info, sizeof(si32)); 209244172Skib } 210244172Skib return (error); 211244172Skib} 212244172Skib 213128597Smarcel#ifdef COMPAT_FREEBSD4 214174526Sjhbstatic void 215100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out) 216100384Speter{ 217172003Sjhb 218174424Sscottl statfs_scale_blocks(in, INT32_MAX); 219156266Sps bzero(out, sizeof(*out)); 220100384Speter CP(*in, *out, f_bsize); 221172003Sjhb out->f_iosize = MIN(in->f_iosize, INT32_MAX); 222100384Speter CP(*in, *out, f_blocks); 223100384Speter CP(*in, *out, f_bfree); 224100384Speter CP(*in, *out, f_bavail); 225172003Sjhb out->f_files = MIN(in->f_files, INT32_MAX); 226174526Sjhb out->f_ffree = MIN(in->f_ffree, INT32_MAX); 227100384Speter CP(*in, *out, f_fsid); 228100384Speter CP(*in, *out, f_owner); 229100384Speter CP(*in, *out, f_type); 230100384Speter CP(*in, *out, f_flags); 231174526Sjhb out->f_syncwrites = MIN(in->f_syncwrites, INT32_MAX); 232174526Sjhb out->f_asyncwrites = MIN(in->f_asyncwrites, INT32_MAX); 233156266Sps strlcpy(out->f_fstypename, 234156266Sps in->f_fstypename, MFSNAMELEN); 235156266Sps strlcpy(out->f_mntonname, 236156266Sps in->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 237174526Sjhb out->f_syncreads = MIN(in->f_syncreads, INT32_MAX); 238174526Sjhb out->f_asyncreads = MIN(in->f_asyncreads, INT32_MAX); 239156266Sps strlcpy(out->f_mntfromname, 240156266Sps in->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 241100384Speter} 242128597Smarcel#endif 243100384Speter 244128597Smarcel#ifdef COMPAT_FREEBSD4 245100384Speterint 246128260Speterfreebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap) 247100384Speter{ 248147178Spjd struct statfs *buf, *sp; 249147178Spjd struct statfs32 stat32; 250147178Spjd size_t count, size; 251100384Speter int error; 252100384Speter 253147178Spjd count = uap->bufsize / sizeof(struct statfs32); 254147178Spjd size = count * sizeof(struct statfs); 255147302Spjd error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags); 256147302Spjd if (size > 0) { 257100384Speter count = td->td_retval[0]; 258147178Spjd sp = buf; 259147178Spjd while (count > 0 && error == 0) { 260174526Sjhb copy_statfs(sp, &stat32); 261147178Spjd error = copyout(&stat32, uap->buf, sizeof(stat32)); 262147178Spjd sp++; 263147178Spjd uap->buf++; 264147178Spjd count--; 265100384Speter } 266147178Spjd free(buf, M_TEMP); 267100384Speter } 268100384Speter return (error); 269100384Speter} 270128597Smarcel#endif 271100384Speter 272100384Speterint 273119333Speterfreebsd32_sigaltstack(struct thread *td, 274119333Speter struct freebsd32_sigaltstack_args *uap) 275100384Speter{ 276113859Sjhb struct sigaltstack32 s32; 277113859Sjhb struct sigaltstack ss, oss, *ssp; 278100384Speter int error; 279100384Speter 280113859Sjhb if (uap->ss != NULL) { 281113859Sjhb error = copyin(uap->ss, &s32, sizeof(s32)); 282100384Speter if (error) 283100384Speter return (error); 284113859Sjhb PTRIN_CP(s32, ss, ss_sp); 285113859Sjhb CP(s32, ss, ss_size); 286113859Sjhb CP(s32, ss, ss_flags); 287113859Sjhb ssp = &ss; 288113859Sjhb } else 289113859Sjhb ssp = NULL; 290113859Sjhb error = kern_sigaltstack(td, ssp, &oss); 291113859Sjhb if (error == 0 && uap->oss != NULL) { 292113859Sjhb PTROUT_CP(oss, s32, ss_sp); 293113859Sjhb CP(oss, s32, ss_size); 294113859Sjhb CP(oss, s32, ss_flags); 295113859Sjhb error = copyout(&s32, uap->oss, sizeof(s32)); 296100384Speter } 297100384Speter return (error); 298100384Speter} 299100384Speter 300142059Sjhb/* 301142059Sjhb * Custom version of exec_copyin_args() so that we can translate 302142059Sjhb * the pointers. 303142059Sjhb */ 304210431Skibint 305142059Sjhbfreebsd32_exec_copyin_args(struct image_args *args, char *fname, 306142059Sjhb enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv) 307100384Speter{ 308142059Sjhb char *argp, *envp; 309142059Sjhb u_int32_t *p32, arg; 310142059Sjhb size_t length; 311100384Speter int error; 312100384Speter 313142059Sjhb bzero(args, sizeof(*args)); 314142059Sjhb if (argv == NULL) 315142059Sjhb return (EFAULT); 316100384Speter 317142059Sjhb /* 318210545Salc * Allocate demand-paged memory for the file name, argument, and 319210545Salc * environment strings. 320142059Sjhb */ 321210545Salc error = exec_alloc_args(args); 322210545Salc if (error != 0) 323210545Salc return (error); 324142059Sjhb 325142059Sjhb /* 326142059Sjhb * Copy the file name. 327142059Sjhb */ 328177789Skib if (fname != NULL) { 329210545Salc args->fname = args->buf; 330177789Skib error = (segflg == UIO_SYSSPACE) ? 331177789Skib copystr(fname, args->fname, PATH_MAX, &length) : 332177789Skib copyinstr(fname, args->fname, PATH_MAX, &length); 333177789Skib if (error != 0) 334177789Skib goto err_exit; 335177789Skib } else 336210475Salc length = 0; 337142059Sjhb 338210545Salc args->begin_argv = args->buf + length; 339210475Salc args->endp = args->begin_argv; 340210475Salc args->stringspace = ARG_MAX; 341210475Salc 342142059Sjhb /* 343142059Sjhb * extract arguments first 344142059Sjhb */ 345142059Sjhb p32 = argv; 346142059Sjhb for (;;) { 347142059Sjhb error = copyin(p32++, &arg, sizeof(arg)); 348142059Sjhb if (error) 349156440Sups goto err_exit; 350142059Sjhb if (arg == 0) 351142059Sjhb break; 352142059Sjhb argp = PTRIN(arg); 353142059Sjhb error = copyinstr(argp, args->endp, args->stringspace, &length); 354142059Sjhb if (error) { 355142059Sjhb if (error == ENAMETOOLONG) 356156440Sups error = E2BIG; 357156440Sups goto err_exit; 358142059Sjhb } 359142059Sjhb args->stringspace -= length; 360142059Sjhb args->endp += length; 361142059Sjhb args->argc++; 362100384Speter } 363142059Sjhb 364142059Sjhb args->begin_envv = args->endp; 365142059Sjhb 366142059Sjhb /* 367142059Sjhb * extract environment strings 368142059Sjhb */ 369142059Sjhb if (envv) { 370142059Sjhb p32 = envv; 371142059Sjhb for (;;) { 372100384Speter error = copyin(p32++, &arg, sizeof(arg)); 373100384Speter if (error) 374156440Sups goto err_exit; 375142059Sjhb if (arg == 0) 376142059Sjhb break; 377142059Sjhb envp = PTRIN(arg); 378142059Sjhb error = copyinstr(envp, args->endp, args->stringspace, 379142059Sjhb &length); 380142059Sjhb if (error) { 381142059Sjhb if (error == ENAMETOOLONG) 382156440Sups error = E2BIG; 383156440Sups goto err_exit; 384142059Sjhb } 385142059Sjhb args->stringspace -= length; 386142059Sjhb args->endp += length; 387142059Sjhb args->envc++; 388142059Sjhb } 389100384Speter } 390100384Speter 391142059Sjhb return (0); 392156440Sups 393156440Supserr_exit: 394210429Salc exec_free_args(args); 395156440Sups return (error); 396100384Speter} 397100384Speter 398142059Sjhbint 399142059Sjhbfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) 400142059Sjhb{ 401142059Sjhb struct image_args eargs; 402142059Sjhb int error; 403142059Sjhb 404142059Sjhb error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE, 405142059Sjhb uap->argv, uap->envv); 406142059Sjhb if (error == 0) 407142059Sjhb error = kern_execve(td, &eargs, NULL); 408142059Sjhb return (error); 409142059Sjhb} 410142059Sjhb 411177789Skibint 412177789Skibfreebsd32_fexecve(struct thread *td, struct freebsd32_fexecve_args *uap) 413177789Skib{ 414177789Skib struct image_args eargs; 415177789Skib int error; 416177789Skib 417177789Skib error = freebsd32_exec_copyin_args(&eargs, NULL, UIO_SYSSPACE, 418177789Skib uap->argv, uap->envv); 419177789Skib if (error == 0) { 420177789Skib eargs.fd = uap->fd; 421177789Skib error = kern_execve(td, &eargs, NULL); 422177789Skib } 423177789Skib return (error); 424177789Skib} 425177789Skib 426114987Speter#ifdef __ia64__ 427100384Speterstatic int 428119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 429119333Speter int prot, int fd, off_t pos) 430100384Speter{ 431100384Speter vm_map_t map; 432100384Speter vm_map_entry_t entry; 433100384Speter int rv; 434100384Speter 435100384Speter map = &td->td_proc->p_vmspace->vm_map; 436100384Speter if (fd != -1) 437100384Speter prot |= VM_PROT_WRITE; 438100384Speter 439100384Speter if (vm_map_lookup_entry(map, start, &entry)) { 440100384Speter if ((entry->protection & prot) != prot) { 441100384Speter rv = vm_map_protect(map, 442100384Speter trunc_page(start), 443100384Speter round_page(end), 444100384Speter entry->protection | prot, 445100384Speter FALSE); 446100384Speter if (rv != KERN_SUCCESS) 447100384Speter return (EINVAL); 448100384Speter } 449100384Speter } else { 450100384Speter vm_offset_t addr = trunc_page(start); 451100384Speter rv = vm_map_find(map, 0, 0, 452100384Speter &addr, PAGE_SIZE, FALSE, prot, 453100384Speter VM_PROT_ALL, 0); 454100384Speter if (rv != KERN_SUCCESS) 455100384Speter return (EINVAL); 456100384Speter } 457100384Speter 458100384Speter if (fd != -1) { 459100384Speter struct pread_args r; 460107849Salfred r.fd = fd; 461107849Salfred r.buf = (void *) start; 462107849Salfred r.nbyte = end - start; 463107849Salfred r.offset = pos; 464225617Skmacy return (sys_pread(td, &r)); 465100384Speter } else { 466100384Speter while (start < end) { 467100384Speter subyte((void *) start, 0); 468100384Speter start++; 469100384Speter } 470100384Speter return (0); 471100384Speter } 472100384Speter} 473114987Speter#endif 474100384Speter 475100384Speterint 476237134Skibfreebsd32_mprotect(struct thread *td, struct freebsd32_mprotect_args *uap) 477237134Skib{ 478237134Skib struct mprotect_args ap; 479237134Skib 480237134Skib ap.addr = PTRIN(uap->addr); 481237134Skib ap.len = uap->len; 482237134Skib ap.prot = uap->prot; 483237134Skib#if defined(__amd64__) || defined(__ia64__) 484237134Skib if (i386_read_exec && (ap.prot & PROT_READ) != 0) 485237134Skib ap.prot |= PROT_EXEC; 486237134Skib#endif 487237134Skib return (sys_mprotect(td, &ap)); 488237134Skib} 489237134Skib 490237134Skibint 491119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) 492100384Speter{ 493100384Speter struct mmap_args ap; 494107849Salfred vm_offset_t addr = (vm_offset_t) uap->addr; 495107849Salfred vm_size_t len = uap->len; 496107849Salfred int prot = uap->prot; 497107849Salfred int flags = uap->flags; 498107849Salfred int fd = uap->fd; 499205014Snwhitehorn off_t pos = PAIR32TO64(off_t,uap->pos); 500114987Speter#ifdef __ia64__ 501100384Speter vm_size_t pageoff; 502100384Speter int error; 503100384Speter 504100384Speter /* 505100384Speter * Attempt to handle page size hassles. 506100384Speter */ 507100384Speter pageoff = (pos & PAGE_MASK); 508100384Speter if (flags & MAP_FIXED) { 509100384Speter vm_offset_t start, end; 510100384Speter start = addr; 511100384Speter end = addr + len; 512100384Speter 513100384Speter if (start != trunc_page(start)) { 514119333Speter error = freebsd32_mmap_partial(td, start, 515119333Speter round_page(start), prot, 516119333Speter fd, pos); 517100384Speter if (fd != -1) 518100384Speter pos += round_page(start) - start; 519100384Speter start = round_page(start); 520100384Speter } 521100384Speter if (end != round_page(end)) { 522100384Speter vm_offset_t t = trunc_page(end); 523119333Speter error = freebsd32_mmap_partial(td, t, end, 524100384Speter prot, fd, 525100384Speter pos + t - start); 526100384Speter end = trunc_page(end); 527100384Speter } 528100384Speter if (end > start && fd != -1 && (pos & PAGE_MASK)) { 529100384Speter /* 530100384Speter * We can't map this region at all. The specified 531100384Speter * address doesn't have the same alignment as the file 532100384Speter * position. Fake the mapping by simply reading the 533100384Speter * entire region into memory. First we need to make 534100384Speter * sure the region exists. 535100384Speter */ 536100384Speter vm_map_t map; 537100384Speter struct pread_args r; 538100384Speter int rv; 539100384Speter 540100384Speter prot |= VM_PROT_WRITE; 541100384Speter map = &td->td_proc->p_vmspace->vm_map; 542100384Speter rv = vm_map_remove(map, start, end); 543169181Salc if (rv != KERN_SUCCESS) 544100384Speter return (EINVAL); 545100384Speter rv = vm_map_find(map, 0, 0, 546100384Speter &start, end - start, FALSE, 547100384Speter prot, VM_PROT_ALL, 0); 548100384Speter if (rv != KERN_SUCCESS) 549100384Speter return (EINVAL); 550107849Salfred r.fd = fd; 551107849Salfred r.buf = (void *) start; 552107849Salfred r.nbyte = end - start; 553107849Salfred r.offset = pos; 554225617Skmacy error = sys_pread(td, &r); 555100384Speter if (error) 556100384Speter return (error); 557100384Speter 558100384Speter td->td_retval[0] = addr; 559100384Speter return (0); 560100384Speter } 561100384Speter if (end == start) { 562100384Speter /* 563100384Speter * After dealing with the ragged ends, there 564100384Speter * might be none left. 565100384Speter */ 566100384Speter td->td_retval[0] = addr; 567100384Speter return (0); 568100384Speter } 569100384Speter addr = start; 570100384Speter len = end - start; 571100384Speter } 572114987Speter#endif 573100384Speter 574237134Skib#if defined(__amd64__) || defined(__ia64__) 575237134Skib if (i386_read_exec && (prot & PROT_READ)) 576237134Skib prot |= PROT_EXEC; 577237134Skib#endif 578237134Skib 579107849Salfred ap.addr = (void *) addr; 580107849Salfred ap.len = len; 581107849Salfred ap.prot = prot; 582107849Salfred ap.flags = flags; 583107849Salfred ap.fd = fd; 584107849Salfred ap.pos = pos; 585100384Speter 586225617Skmacy return (sys_mmap(td, &ap)); 587100384Speter} 588100384Speter 589171215Speter#ifdef COMPAT_FREEBSD6 590171215Speterint 591171215Speterfreebsd6_freebsd32_mmap(struct thread *td, struct freebsd6_freebsd32_mmap_args *uap) 592171215Speter{ 593171215Speter struct freebsd32_mmap_args ap; 594171215Speter 595171215Speter ap.addr = uap->addr; 596171215Speter ap.len = uap->len; 597171215Speter ap.prot = uap->prot; 598171215Speter ap.flags = uap->flags; 599171215Speter ap.fd = uap->fd; 600205014Snwhitehorn ap.pos1 = uap->pos1; 601205014Snwhitehorn ap.pos2 = uap->pos2; 602171215Speter 603171215Speter return (freebsd32_mmap(td, &ap)); 604171215Speter} 605171215Speter#endif 606171215Speter 607100384Speterint 608119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) 609100384Speter{ 610142059Sjhb struct itimerval itv, oitv, *itvp; 611142059Sjhb struct itimerval32 i32; 612100384Speter int error; 613100384Speter 614142059Sjhb if (uap->itv != NULL) { 615142059Sjhb error = copyin(uap->itv, &i32, sizeof(i32)); 616100384Speter if (error) 617100384Speter return (error); 618142059Sjhb TV_CP(i32, itv, it_interval); 619142059Sjhb TV_CP(i32, itv, it_value); 620142059Sjhb itvp = &itv; 621142059Sjhb } else 622142059Sjhb itvp = NULL; 623142059Sjhb error = kern_setitimer(td, uap->which, itvp, &oitv); 624142059Sjhb if (error || uap->oitv == NULL) 625100384Speter return (error); 626142059Sjhb TV_CP(oitv, i32, it_interval); 627142059Sjhb TV_CP(oitv, i32, it_value); 628142059Sjhb return (copyout(&i32, uap->oitv, sizeof(i32))); 629100384Speter} 630100384Speter 631100384Speterint 632125171Speterfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap) 633125171Speter{ 634142059Sjhb struct itimerval itv; 635142059Sjhb struct itimerval32 i32; 636125171Speter int error; 637125171Speter 638142059Sjhb error = kern_getitimer(td, uap->which, &itv); 639142059Sjhb if (error || uap->itv == NULL) 640125171Speter return (error); 641142059Sjhb TV_CP(itv, i32, it_interval); 642142059Sjhb TV_CP(itv, i32, it_value); 643142059Sjhb return (copyout(&i32, uap->itv, sizeof(i32))); 644125171Speter} 645125171Speter 646125171Speterint 647119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap) 648100384Speter{ 649142059Sjhb struct timeval32 tv32; 650142059Sjhb struct timeval tv, *tvp; 651100384Speter int error; 652100384Speter 653142059Sjhb if (uap->tv != NULL) { 654142059Sjhb error = copyin(uap->tv, &tv32, sizeof(tv32)); 655100384Speter if (error) 656100384Speter return (error); 657142059Sjhb CP(tv32, tv, tv_sec); 658142059Sjhb CP(tv32, tv, tv_usec); 659142059Sjhb tvp = &tv; 660142059Sjhb } else 661142059Sjhb tvp = NULL; 662100384Speter /* 663142059Sjhb * XXX Do pointers need PTRIN()? 664100384Speter */ 665197049Skib return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp, 666197049Skib sizeof(int32_t) * 8)); 667100384Speter} 668100384Speter 669198508Skibint 670198508Skibfreebsd32_pselect(struct thread *td, struct freebsd32_pselect_args *uap) 671198508Skib{ 672198508Skib struct timespec32 ts32; 673198508Skib struct timespec ts; 674198508Skib struct timeval tv, *tvp; 675198508Skib sigset_t set, *uset; 676198508Skib int error; 677198508Skib 678198508Skib if (uap->ts != NULL) { 679198508Skib error = copyin(uap->ts, &ts32, sizeof(ts32)); 680198508Skib if (error != 0) 681198508Skib return (error); 682198508Skib CP(ts32, ts, tv_sec); 683198508Skib CP(ts32, ts, tv_nsec); 684198508Skib TIMESPEC_TO_TIMEVAL(&tv, &ts); 685198508Skib tvp = &tv; 686198508Skib } else 687198508Skib tvp = NULL; 688198508Skib if (uap->sm != NULL) { 689198508Skib error = copyin(uap->sm, &set, sizeof(set)); 690198508Skib if (error != 0) 691198508Skib return (error); 692198508Skib uset = &set; 693198508Skib } else 694198508Skib uset = NULL; 695198508Skib /* 696198508Skib * XXX Do pointers need PTRIN()? 697198508Skib */ 698198508Skib error = kern_pselect(td, uap->nd, uap->in, uap->ou, uap->ex, tvp, 699198508Skib uset, sizeof(int32_t) * 8); 700198508Skib return (error); 701198508Skib} 702198508Skib 703146950Sps/* 704146950Sps * Copy 'count' items into the destination list pointed to by uap->eventlist. 705146950Sps */ 706146950Spsstatic int 707146950Spsfreebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count) 708146950Sps{ 709146950Sps struct freebsd32_kevent_args *uap; 710146950Sps struct kevent32 ks32[KQ_NEVENTS]; 711146950Sps int i, error = 0; 712146950Sps 713146950Sps KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 714146950Sps uap = (struct freebsd32_kevent_args *)arg; 715146950Sps 716146950Sps for (i = 0; i < count; i++) { 717146950Sps CP(kevp[i], ks32[i], ident); 718146950Sps CP(kevp[i], ks32[i], filter); 719146950Sps CP(kevp[i], ks32[i], flags); 720146950Sps CP(kevp[i], ks32[i], fflags); 721146950Sps CP(kevp[i], ks32[i], data); 722146950Sps PTROUT_CP(kevp[i], ks32[i], udata); 723146950Sps } 724146950Sps error = copyout(ks32, uap->eventlist, count * sizeof *ks32); 725146950Sps if (error == 0) 726146950Sps uap->eventlist += count; 727146950Sps return (error); 728146950Sps} 729146950Sps 730146950Sps/* 731146950Sps * Copy 'count' items from the list pointed to by uap->changelist. 732146950Sps */ 733146950Spsstatic int 734146950Spsfreebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count) 735146950Sps{ 736146950Sps struct freebsd32_kevent_args *uap; 737146950Sps struct kevent32 ks32[KQ_NEVENTS]; 738146950Sps int i, error = 0; 739146950Sps 740146950Sps KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 741146950Sps uap = (struct freebsd32_kevent_args *)arg; 742146950Sps 743146950Sps error = copyin(uap->changelist, ks32, count * sizeof *ks32); 744146950Sps if (error) 745146950Sps goto done; 746146950Sps uap->changelist += count; 747146950Sps 748146950Sps for (i = 0; i < count; i++) { 749146950Sps CP(ks32[i], kevp[i], ident); 750146950Sps CP(ks32[i], kevp[i], filter); 751146950Sps CP(ks32[i], kevp[i], flags); 752146950Sps CP(ks32[i], kevp[i], fflags); 753146950Sps CP(ks32[i], kevp[i], data); 754146950Sps PTRIN_CP(ks32[i], kevp[i], udata); 755146950Sps } 756146950Spsdone: 757146950Sps return (error); 758146950Sps} 759146950Sps 760100384Speterint 761119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) 762114987Speter{ 763114987Speter struct timespec32 ts32; 764142934Sps struct timespec ts, *tsp; 765146950Sps struct kevent_copyops k_ops = { uap, 766146950Sps freebsd32_kevent_copyout, 767146950Sps freebsd32_kevent_copyin}; 768146950Sps int error; 769114987Speter 770114987Speter 771114987Speter if (uap->timeout) { 772114987Speter error = copyin(uap->timeout, &ts32, sizeof(ts32)); 773114987Speter if (error) 774114987Speter return (error); 775114987Speter CP(ts32, ts, tv_sec); 776114987Speter CP(ts32, ts, tv_nsec); 777142934Sps tsp = &ts; 778142934Sps } else 779142934Sps tsp = NULL; 780146950Sps error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents, 781146950Sps &k_ops, tsp); 782142934Sps return (error); 783114987Speter} 784114987Speter 785114987Speterint 786119333Speterfreebsd32_gettimeofday(struct thread *td, 787119333Speter struct freebsd32_gettimeofday_args *uap) 788100384Speter{ 789123425Speter struct timeval atv; 790123425Speter struct timeval32 atv32; 791123425Speter struct timezone rtz; 792123425Speter int error = 0; 793100384Speter 794123425Speter if (uap->tp) { 795123425Speter microtime(&atv); 796123425Speter CP(atv, atv32, tv_sec); 797123425Speter CP(atv, atv32, tv_usec); 798123425Speter error = copyout(&atv32, uap->tp, sizeof (atv32)); 799100384Speter } 800123425Speter if (error == 0 && uap->tzp != NULL) { 801123425Speter rtz.tz_minuteswest = tz_minuteswest; 802123425Speter rtz.tz_dsttime = tz_dsttime; 803123425Speter error = copyout(&rtz, uap->tzp, sizeof (rtz)); 804100384Speter } 805100384Speter return (error); 806100384Speter} 807100384Speter 808100384Speterint 809119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) 810100384Speter{ 811136152Sjhb struct rusage32 s32; 812136152Sjhb struct rusage s; 813100384Speter int error; 814100384Speter 815136152Sjhb error = kern_getrusage(td, uap->who, &s); 816100384Speter if (error) 817100384Speter return (error); 818136152Sjhb if (uap->rusage != NULL) { 819207007Skib freebsd32_rusage_out(&s, &s32); 820136152Sjhb error = copyout(&s32, uap->rusage, sizeof(s32)); 821100384Speter } 822100384Speter return (error); 823100384Speter} 824100384Speter 825144450Sjhbstatic int 826144450Sjhbfreebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop) 827100384Speter{ 828144450Sjhb struct iovec32 iov32; 829144450Sjhb struct iovec *iov; 830144450Sjhb struct uio *uio; 831144450Sjhb u_int iovlen; 832144450Sjhb int error, i; 833100384Speter 834144450Sjhb *uiop = NULL; 835144450Sjhb if (iovcnt > UIO_MAXIOV) 836100384Speter return (EINVAL); 837144450Sjhb iovlen = iovcnt * sizeof(struct iovec); 838144450Sjhb uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK); 839144450Sjhb iov = (struct iovec *)(uio + 1); 840144450Sjhb for (i = 0; i < iovcnt; i++) { 841144450Sjhb error = copyin(&iovp[i], &iov32, sizeof(struct iovec32)); 842144450Sjhb if (error) { 843144450Sjhb free(uio, M_IOV); 844144450Sjhb return (error); 845144450Sjhb } 846144450Sjhb iov[i].iov_base = PTRIN(iov32.iov_base); 847144450Sjhb iov[i].iov_len = iov32.iov_len; 848100384Speter } 849144450Sjhb uio->uio_iov = iov; 850144450Sjhb uio->uio_iovcnt = iovcnt; 851144450Sjhb uio->uio_segflg = UIO_USERSPACE; 852144450Sjhb uio->uio_offset = -1; 853144450Sjhb uio->uio_resid = 0; 854144450Sjhb for (i = 0; i < iovcnt; i++) { 855144450Sjhb if (iov->iov_len > INT_MAX - uio->uio_resid) { 856144450Sjhb free(uio, M_IOV); 857144450Sjhb return (EINVAL); 858144450Sjhb } 859144450Sjhb uio->uio_resid += iov->iov_len; 860144450Sjhb iov++; 861144450Sjhb } 862144450Sjhb *uiop = uio; 863144450Sjhb return (0); 864144450Sjhb} 865100384Speter 866144450Sjhbint 867144450Sjhbfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) 868144450Sjhb{ 869144450Sjhb struct uio *auio; 870144450Sjhb int error; 871100384Speter 872144450Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 873144450Sjhb if (error) 874144450Sjhb return (error); 875144450Sjhb error = kern_readv(td, uap->fd, auio); 876144450Sjhb free(auio, M_IOV); 877100384Speter return (error); 878100384Speter} 879100384Speter 880100384Speterint 881119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) 882100384Speter{ 883144450Sjhb struct uio *auio; 884144450Sjhb int error; 885100384Speter 886144450Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 887144450Sjhb if (error) 888144450Sjhb return (error); 889144450Sjhb error = kern_writev(td, uap->fd, auio); 890144450Sjhb free(auio, M_IOV); 891100384Speter return (error); 892100384Speter} 893100384Speter 894100384Speterint 895147813Sjhbfreebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap) 896147813Sjhb{ 897147813Sjhb struct uio *auio; 898147813Sjhb int error; 899147813Sjhb 900147813Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 901147813Sjhb if (error) 902147813Sjhb return (error); 903205014Snwhitehorn error = kern_preadv(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset)); 904147813Sjhb free(auio, M_IOV); 905147813Sjhb return (error); 906147813Sjhb} 907147813Sjhb 908147813Sjhbint 909147813Sjhbfreebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap) 910147813Sjhb{ 911147813Sjhb struct uio *auio; 912147813Sjhb int error; 913147813Sjhb 914147813Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 915147813Sjhb if (error) 916147813Sjhb return (error); 917205014Snwhitehorn error = kern_pwritev(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset)); 918147813Sjhb free(auio, M_IOV); 919147813Sjhb return (error); 920147813Sjhb} 921147813Sjhb 922205319Skibint 923151909Spsfreebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp, 924151359Sps int error) 925151359Sps{ 926151359Sps struct iovec32 iov32; 927151909Sps struct iovec *iov; 928151909Sps u_int iovlen; 929151359Sps int i; 930151359Sps 931151909Sps *iovp = NULL; 932151359Sps if (iovcnt > UIO_MAXIOV) 933151359Sps return (error); 934151359Sps iovlen = iovcnt * sizeof(struct iovec); 935151909Sps iov = malloc(iovlen, M_IOV, M_WAITOK); 936151359Sps for (i = 0; i < iovcnt; i++) { 937151909Sps error = copyin(&iovp32[i], &iov32, sizeof(struct iovec32)); 938151359Sps if (error) { 939151909Sps free(iov, M_IOV); 940151359Sps return (error); 941151359Sps } 942151909Sps iov[i].iov_base = PTRIN(iov32.iov_base); 943151909Sps iov[i].iov_len = iov32.iov_len; 944151359Sps } 945151909Sps *iovp = iov; 946151359Sps return (0); 947151359Sps} 948151359Sps 949151359Spsstatic int 950151359Spsfreebsd32_copyinmsghdr(struct msghdr32 *msg32, struct msghdr *msg) 951151359Sps{ 952151359Sps struct msghdr32 m32; 953151359Sps int error; 954151359Sps 955151359Sps error = copyin(msg32, &m32, sizeof(m32)); 956151359Sps if (error) 957151359Sps return (error); 958151359Sps msg->msg_name = PTRIN(m32.msg_name); 959151359Sps msg->msg_namelen = m32.msg_namelen; 960151359Sps msg->msg_iov = PTRIN(m32.msg_iov); 961151359Sps msg->msg_iovlen = m32.msg_iovlen; 962151359Sps msg->msg_control = PTRIN(m32.msg_control); 963151359Sps msg->msg_controllen = m32.msg_controllen; 964151359Sps msg->msg_flags = m32.msg_flags; 965151909Sps return (0); 966151359Sps} 967151359Sps 968151359Spsstatic int 969151359Spsfreebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32) 970151359Sps{ 971151359Sps struct msghdr32 m32; 972151359Sps int error; 973151359Sps 974151359Sps m32.msg_name = PTROUT(msg->msg_name); 975151359Sps m32.msg_namelen = msg->msg_namelen; 976151359Sps m32.msg_iov = PTROUT(msg->msg_iov); 977151359Sps m32.msg_iovlen = msg->msg_iovlen; 978151359Sps m32.msg_control = PTROUT(msg->msg_control); 979151359Sps m32.msg_controllen = msg->msg_controllen; 980151359Sps m32.msg_flags = msg->msg_flags; 981151359Sps error = copyout(&m32, msg32, sizeof(m32)); 982151359Sps return (error); 983151359Sps} 984151359Sps 985151909Sps#define FREEBSD32_ALIGNBYTES (sizeof(int) - 1) 986151909Sps#define FREEBSD32_ALIGN(p) \ 987151909Sps (((u_long)(p) + FREEBSD32_ALIGNBYTES) & ~FREEBSD32_ALIGNBYTES) 988151909Sps#define FREEBSD32_CMSG_SPACE(l) \ 989151909Sps (FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + FREEBSD32_ALIGN(l)) 990151909Sps 991151909Sps#define FREEBSD32_CMSG_DATA(cmsg) ((unsigned char *)(cmsg) + \ 992151909Sps FREEBSD32_ALIGN(sizeof(struct cmsghdr))) 993151909Spsstatic int 994151909Spsfreebsd32_copy_msg_out(struct msghdr *msg, struct mbuf *control) 995151909Sps{ 996151909Sps struct cmsghdr *cm; 997151909Sps void *data; 998151909Sps socklen_t clen, datalen; 999151909Sps int error; 1000151909Sps caddr_t ctlbuf; 1001151909Sps int len, maxlen, copylen; 1002151909Sps struct mbuf *m; 1003151909Sps error = 0; 1004151909Sps 1005151909Sps len = msg->msg_controllen; 1006151909Sps maxlen = msg->msg_controllen; 1007151909Sps msg->msg_controllen = 0; 1008151909Sps 1009151909Sps m = control; 1010151909Sps ctlbuf = msg->msg_control; 1011151909Sps 1012151909Sps while (m && len > 0) { 1013151909Sps cm = mtod(m, struct cmsghdr *); 1014151909Sps clen = m->m_len; 1015151909Sps 1016151909Sps while (cm != NULL) { 1017151909Sps 1018151909Sps if (sizeof(struct cmsghdr) > clen || 1019151909Sps cm->cmsg_len > clen) { 1020151909Sps error = EINVAL; 1021151909Sps break; 1022151909Sps } 1023151909Sps 1024151909Sps data = CMSG_DATA(cm); 1025151909Sps datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data; 1026151909Sps 1027151909Sps /* Adjust message length */ 1028151909Sps cm->cmsg_len = FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + 1029151909Sps datalen; 1030151909Sps 1031151909Sps 1032151909Sps /* Copy cmsghdr */ 1033151909Sps copylen = sizeof(struct cmsghdr); 1034151909Sps if (len < copylen) { 1035151909Sps msg->msg_flags |= MSG_CTRUNC; 1036151909Sps copylen = len; 1037151909Sps } 1038151909Sps 1039151909Sps error = copyout(cm,ctlbuf,copylen); 1040151909Sps if (error) 1041151909Sps goto exit; 1042151909Sps 1043151909Sps ctlbuf += FREEBSD32_ALIGN(copylen); 1044151909Sps len -= FREEBSD32_ALIGN(copylen); 1045151909Sps 1046151909Sps if (len <= 0) 1047151909Sps break; 1048151909Sps 1049151909Sps /* Copy data */ 1050151909Sps copylen = datalen; 1051151909Sps if (len < copylen) { 1052151909Sps msg->msg_flags |= MSG_CTRUNC; 1053151909Sps copylen = len; 1054151909Sps } 1055151909Sps 1056151909Sps error = copyout(data,ctlbuf,copylen); 1057151909Sps if (error) 1058151909Sps goto exit; 1059151909Sps 1060151909Sps ctlbuf += FREEBSD32_ALIGN(copylen); 1061151909Sps len -= FREEBSD32_ALIGN(copylen); 1062151909Sps 1063151909Sps if (CMSG_SPACE(datalen) < clen) { 1064151909Sps clen -= CMSG_SPACE(datalen); 1065151909Sps cm = (struct cmsghdr *) 1066151909Sps ((caddr_t)cm + CMSG_SPACE(datalen)); 1067151909Sps } else { 1068151909Sps clen = 0; 1069151909Sps cm = NULL; 1070151909Sps } 1071151909Sps } 1072151909Sps m = m->m_next; 1073151909Sps } 1074151909Sps 1075151909Sps msg->msg_controllen = (len <= 0) ? maxlen : ctlbuf - (caddr_t)msg->msg_control; 1076151909Sps 1077151909Spsexit: 1078151909Sps return (error); 1079151909Sps 1080151909Sps} 1081151909Sps 1082147813Sjhbint 1083151359Spsfreebsd32_recvmsg(td, uap) 1084151359Sps struct thread *td; 1085151359Sps struct freebsd32_recvmsg_args /* { 1086151359Sps int s; 1087151359Sps struct msghdr32 *msg; 1088151359Sps int flags; 1089151359Sps } */ *uap; 1090151359Sps{ 1091151359Sps struct msghdr msg; 1092151359Sps struct msghdr32 m32; 1093151359Sps struct iovec *uiov, *iov; 1094151909Sps struct mbuf *control = NULL; 1095151909Sps struct mbuf **controlp; 1096151909Sps 1097151359Sps int error; 1098151359Sps error = copyin(uap->msg, &m32, sizeof(m32)); 1099151359Sps if (error) 1100151359Sps return (error); 1101151359Sps error = freebsd32_copyinmsghdr(uap->msg, &msg); 1102151359Sps if (error) 1103151359Sps return (error); 1104160246Sjhb error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov, 1105160246Sjhb EMSGSIZE); 1106151359Sps if (error) 1107151359Sps return (error); 1108151359Sps msg.msg_flags = uap->flags; 1109151359Sps uiov = msg.msg_iov; 1110151359Sps msg.msg_iov = iov; 1111151909Sps 1112151909Sps controlp = (msg.msg_control != NULL) ? &control : NULL; 1113160249Sjhb error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, controlp); 1114151359Sps if (error == 0) { 1115151359Sps msg.msg_iov = uiov; 1116151909Sps 1117151909Sps if (control != NULL) 1118151909Sps error = freebsd32_copy_msg_out(&msg, control); 1119210796Skib else 1120210796Skib msg.msg_controllen = 0; 1121151909Sps 1122151909Sps if (error == 0) 1123151909Sps error = freebsd32_copyoutmsghdr(&msg, uap->msg); 1124151359Sps } 1125151359Sps free(iov, M_IOV); 1126151909Sps 1127151909Sps if (control != NULL) 1128151909Sps m_freem(control); 1129151909Sps 1130151359Sps return (error); 1131151359Sps} 1132151359Sps 1133151909Sps 1134151909Spsstatic int 1135151909Spsfreebsd32_convert_msg_in(struct mbuf **controlp) 1136151909Sps{ 1137151909Sps struct mbuf *control = *controlp; 1138151909Sps struct cmsghdr *cm = mtod(control, struct cmsghdr *); 1139151909Sps void *data; 1140151909Sps socklen_t clen = control->m_len, datalen; 1141151909Sps int error; 1142151909Sps 1143151909Sps error = 0; 1144151909Sps *controlp = NULL; 1145151909Sps 1146151909Sps while (cm != NULL) { 1147151909Sps if (sizeof(struct cmsghdr) > clen || cm->cmsg_len > clen) { 1148151909Sps error = EINVAL; 1149151909Sps break; 1150151909Sps } 1151151909Sps 1152151909Sps data = FREEBSD32_CMSG_DATA(cm); 1153151909Sps datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data; 1154151909Sps 1155151909Sps *controlp = sbcreatecontrol(data, datalen, cm->cmsg_type, 1156151909Sps cm->cmsg_level); 1157151909Sps controlp = &(*controlp)->m_next; 1158151909Sps 1159151909Sps if (FREEBSD32_CMSG_SPACE(datalen) < clen) { 1160151909Sps clen -= FREEBSD32_CMSG_SPACE(datalen); 1161151909Sps cm = (struct cmsghdr *) 1162151909Sps ((caddr_t)cm + FREEBSD32_CMSG_SPACE(datalen)); 1163151909Sps } else { 1164151909Sps clen = 0; 1165151909Sps cm = NULL; 1166151909Sps } 1167151909Sps } 1168151909Sps 1169151909Sps m_freem(control); 1170151909Sps return (error); 1171151909Sps} 1172151909Sps 1173151909Sps 1174151359Spsint 1175151359Spsfreebsd32_sendmsg(struct thread *td, 1176151359Sps struct freebsd32_sendmsg_args *uap) 1177151359Sps{ 1178151359Sps struct msghdr msg; 1179151359Sps struct msghdr32 m32; 1180151359Sps struct iovec *iov; 1181151909Sps struct mbuf *control = NULL; 1182151909Sps struct sockaddr *to = NULL; 1183151359Sps int error; 1184151359Sps 1185151359Sps error = copyin(uap->msg, &m32, sizeof(m32)); 1186151359Sps if (error) 1187151359Sps return (error); 1188151359Sps error = freebsd32_copyinmsghdr(uap->msg, &msg); 1189151359Sps if (error) 1190151359Sps return (error); 1191160246Sjhb error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov, 1192160246Sjhb EMSGSIZE); 1193151359Sps if (error) 1194151359Sps return (error); 1195151359Sps msg.msg_iov = iov; 1196151909Sps if (msg.msg_name != NULL) { 1197151909Sps error = getsockaddr(&to, msg.msg_name, msg.msg_namelen); 1198151909Sps if (error) { 1199151909Sps to = NULL; 1200151909Sps goto out; 1201151909Sps } 1202151909Sps msg.msg_name = to; 1203151909Sps } 1204151909Sps 1205151909Sps if (msg.msg_control) { 1206151909Sps if (msg.msg_controllen < sizeof(struct cmsghdr)) { 1207151909Sps error = EINVAL; 1208151909Sps goto out; 1209151909Sps } 1210151909Sps 1211151909Sps error = sockargs(&control, msg.msg_control, 1212151909Sps msg.msg_controllen, MT_CONTROL); 1213151909Sps if (error) 1214151909Sps goto out; 1215151909Sps 1216151909Sps error = freebsd32_convert_msg_in(&control); 1217151909Sps if (error) 1218151909Sps goto out; 1219151909Sps } 1220151909Sps 1221151909Sps error = kern_sendit(td, uap->s, &msg, uap->flags, control, 1222151909Sps UIO_USERSPACE); 1223151909Sps 1224151909Spsout: 1225151359Sps free(iov, M_IOV); 1226151909Sps if (to) 1227151909Sps free(to, M_SONAME); 1228151359Sps return (error); 1229151359Sps} 1230151359Sps 1231151359Spsint 1232151359Spsfreebsd32_recvfrom(struct thread *td, 1233151359Sps struct freebsd32_recvfrom_args *uap) 1234151359Sps{ 1235151359Sps struct msghdr msg; 1236151359Sps struct iovec aiov; 1237151359Sps int error; 1238151359Sps 1239151359Sps if (uap->fromlenaddr) { 1240160246Sjhb error = copyin(PTRIN(uap->fromlenaddr), &msg.msg_namelen, 1241160246Sjhb sizeof(msg.msg_namelen)); 1242151359Sps if (error) 1243151359Sps return (error); 1244151359Sps } else { 1245151359Sps msg.msg_namelen = 0; 1246151359Sps } 1247151359Sps 1248160246Sjhb msg.msg_name = PTRIN(uap->from); 1249151359Sps msg.msg_iov = &aiov; 1250151359Sps msg.msg_iovlen = 1; 1251160246Sjhb aiov.iov_base = PTRIN(uap->buf); 1252151359Sps aiov.iov_len = uap->len; 1253160246Sjhb msg.msg_control = NULL; 1254151359Sps msg.msg_flags = uap->flags; 1255160249Sjhb error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, NULL); 1256160249Sjhb if (error == 0 && uap->fromlenaddr) 1257160249Sjhb error = copyout(&msg.msg_namelen, PTRIN(uap->fromlenaddr), 1258160249Sjhb sizeof (msg.msg_namelen)); 1259151359Sps return (error); 1260151359Sps} 1261151359Sps 1262151359Spsint 1263119333Speterfreebsd32_settimeofday(struct thread *td, 1264119333Speter struct freebsd32_settimeofday_args *uap) 1265100384Speter{ 1266144450Sjhb struct timeval32 tv32; 1267144450Sjhb struct timeval tv, *tvp; 1268144450Sjhb struct timezone tz, *tzp; 1269100384Speter int error; 1270100384Speter 1271144450Sjhb if (uap->tv) { 1272144450Sjhb error = copyin(uap->tv, &tv32, sizeof(tv32)); 1273100384Speter if (error) 1274100384Speter return (error); 1275144450Sjhb CP(tv32, tv, tv_sec); 1276144450Sjhb CP(tv32, tv, tv_usec); 1277144450Sjhb tvp = &tv; 1278144450Sjhb } else 1279144450Sjhb tvp = NULL; 1280144450Sjhb if (uap->tzp) { 1281144450Sjhb error = copyin(uap->tzp, &tz, sizeof(tz)); 1282100384Speter if (error) 1283100384Speter return (error); 1284144450Sjhb tzp = &tz; 1285144450Sjhb } else 1286144450Sjhb tzp = NULL; 1287144450Sjhb return (kern_settimeofday(td, tvp, tzp)); 1288100384Speter} 1289100384Speter 1290100384Speterint 1291119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) 1292100384Speter{ 1293142059Sjhb struct timeval32 s32[2]; 1294142059Sjhb struct timeval s[2], *sp; 1295100384Speter int error; 1296100384Speter 1297142059Sjhb if (uap->tptr != NULL) { 1298142059Sjhb error = copyin(uap->tptr, s32, sizeof(s32)); 1299100384Speter if (error) 1300100384Speter return (error); 1301100384Speter CP(s32[0], s[0], tv_sec); 1302100384Speter CP(s32[0], s[0], tv_usec); 1303100384Speter CP(s32[1], s[1], tv_sec); 1304100384Speter CP(s32[1], s[1], tv_usec); 1305142059Sjhb sp = s; 1306142059Sjhb } else 1307142059Sjhb sp = NULL; 1308142059Sjhb return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE)); 1309100384Speter} 1310100384Speter 1311100384Speterint 1312154586Sambriskofreebsd32_lutimes(struct thread *td, struct freebsd32_lutimes_args *uap) 1313154586Sambrisko{ 1314154586Sambrisko struct timeval32 s32[2]; 1315154586Sambrisko struct timeval s[2], *sp; 1316154586Sambrisko int error; 1317154586Sambrisko 1318154586Sambrisko if (uap->tptr != NULL) { 1319154586Sambrisko error = copyin(uap->tptr, s32, sizeof(s32)); 1320154586Sambrisko if (error) 1321154586Sambrisko return (error); 1322154586Sambrisko CP(s32[0], s[0], tv_sec); 1323154586Sambrisko CP(s32[0], s[0], tv_usec); 1324154586Sambrisko CP(s32[1], s[1], tv_sec); 1325154586Sambrisko CP(s32[1], s[1], tv_usec); 1326154586Sambrisko sp = s; 1327154586Sambrisko } else 1328154586Sambrisko sp = NULL; 1329154586Sambrisko return (kern_lutimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE)); 1330154586Sambrisko} 1331154586Sambrisko 1332154586Sambriskoint 1333153247Sambriskofreebsd32_futimes(struct thread *td, struct freebsd32_futimes_args *uap) 1334153247Sambrisko{ 1335153247Sambrisko struct timeval32 s32[2]; 1336153247Sambrisko struct timeval s[2], *sp; 1337153247Sambrisko int error; 1338153247Sambrisko 1339153247Sambrisko if (uap->tptr != NULL) { 1340153247Sambrisko error = copyin(uap->tptr, s32, sizeof(s32)); 1341153247Sambrisko if (error) 1342153247Sambrisko return (error); 1343153247Sambrisko CP(s32[0], s[0], tv_sec); 1344153247Sambrisko CP(s32[0], s[0], tv_usec); 1345153247Sambrisko CP(s32[1], s[1], tv_sec); 1346153247Sambrisko CP(s32[1], s[1], tv_usec); 1347153247Sambrisko sp = s; 1348153247Sambrisko } else 1349153247Sambrisko sp = NULL; 1350153247Sambrisko return (kern_futimes(td, uap->fd, sp, UIO_SYSSPACE)); 1351153247Sambrisko} 1352153247Sambrisko 1353177789Skibint 1354177789Skibfreebsd32_futimesat(struct thread *td, struct freebsd32_futimesat_args *uap) 1355177789Skib{ 1356177789Skib struct timeval32 s32[2]; 1357177789Skib struct timeval s[2], *sp; 1358177789Skib int error; 1359153247Sambrisko 1360177789Skib if (uap->times != NULL) { 1361177789Skib error = copyin(uap->times, s32, sizeof(s32)); 1362177789Skib if (error) 1363177789Skib return (error); 1364177789Skib CP(s32[0], s[0], tv_sec); 1365177789Skib CP(s32[0], s[0], tv_usec); 1366177789Skib CP(s32[1], s[1], tv_sec); 1367177789Skib CP(s32[1], s[1], tv_usec); 1368177789Skib sp = s; 1369177789Skib } else 1370177789Skib sp = NULL; 1371177789Skib return (kern_utimesat(td, uap->fd, uap->path, UIO_USERSPACE, 1372177789Skib sp, UIO_SYSSPACE)); 1373177789Skib} 1374177789Skib 1375153247Sambriskoint 1376119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) 1377100384Speter{ 1378144450Sjhb struct timeval32 tv32; 1379144450Sjhb struct timeval delta, olddelta, *deltap; 1380100384Speter int error; 1381100384Speter 1382144450Sjhb if (uap->delta) { 1383144450Sjhb error = copyin(uap->delta, &tv32, sizeof(tv32)); 1384100384Speter if (error) 1385100384Speter return (error); 1386144450Sjhb CP(tv32, delta, tv_sec); 1387144450Sjhb CP(tv32, delta, tv_usec); 1388144450Sjhb deltap = δ 1389144450Sjhb } else 1390144450Sjhb deltap = NULL; 1391144450Sjhb error = kern_adjtime(td, deltap, &olddelta); 1392144450Sjhb if (uap->olddelta && error == 0) { 1393144450Sjhb CP(olddelta, tv32, tv_sec); 1394144450Sjhb CP(olddelta, tv32, tv_usec); 1395144450Sjhb error = copyout(&tv32, uap->olddelta, sizeof(tv32)); 1396100384Speter } 1397100384Speter return (error); 1398100384Speter} 1399100384Speter 1400128597Smarcel#ifdef COMPAT_FREEBSD4 1401100384Speterint 1402128260Speterfreebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap) 1403100384Speter{ 1404142059Sjhb struct statfs32 s32; 1405142059Sjhb struct statfs s; 1406100384Speter int error; 1407100384Speter 1408142059Sjhb error = kern_statfs(td, uap->path, UIO_USERSPACE, &s); 1409100384Speter if (error) 1410100384Speter return (error); 1411174526Sjhb copy_statfs(&s, &s32); 1412142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 1413100384Speter} 1414128597Smarcel#endif 1415100384Speter 1416128597Smarcel#ifdef COMPAT_FREEBSD4 1417100384Speterint 1418128260Speterfreebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap) 1419100384Speter{ 1420142059Sjhb struct statfs32 s32; 1421142059Sjhb struct statfs s; 1422100384Speter int error; 1423100384Speter 1424142059Sjhb error = kern_fstatfs(td, uap->fd, &s); 1425100384Speter if (error) 1426100384Speter return (error); 1427174526Sjhb copy_statfs(&s, &s32); 1428142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 1429100384Speter} 1430128597Smarcel#endif 1431100384Speter 1432128597Smarcel#ifdef COMPAT_FREEBSD4 1433100384Speterint 1434128260Speterfreebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap) 1435128260Speter{ 1436142059Sjhb struct statfs32 s32; 1437142059Sjhb struct statfs s; 1438142059Sjhb fhandle_t fh; 1439128260Speter int error; 1440128260Speter 1441142059Sjhb if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) 1442142059Sjhb return (error); 1443142059Sjhb error = kern_fhstatfs(td, fh, &s); 1444128260Speter if (error) 1445128260Speter return (error); 1446174526Sjhb copy_statfs(&s, &s32); 1447142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 1448128260Speter} 1449128597Smarcel#endif 1450128260Speter 1451128260Speterint 1452119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) 1453100384Speter{ 1454100384Speter struct pread_args ap; 1455100384Speter 1456107849Salfred ap.fd = uap->fd; 1457107849Salfred ap.buf = uap->buf; 1458107849Salfred ap.nbyte = uap->nbyte; 1459205014Snwhitehorn ap.offset = PAIR32TO64(off_t,uap->offset); 1460225617Skmacy return (sys_pread(td, &ap)); 1461100384Speter} 1462100384Speter 1463100384Speterint 1464119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) 1465100384Speter{ 1466100384Speter struct pwrite_args ap; 1467100384Speter 1468107849Salfred ap.fd = uap->fd; 1469107849Salfred ap.buf = uap->buf; 1470107849Salfred ap.nbyte = uap->nbyte; 1471205014Snwhitehorn ap.offset = PAIR32TO64(off_t,uap->offset); 1472225617Skmacy return (sys_pwrite(td, &ap)); 1473100384Speter} 1474100384Speter 1475223166Skib#ifdef COMPAT_43 1476100384Speterint 1477223166Skibofreebsd32_lseek(struct thread *td, struct ofreebsd32_lseek_args *uap) 1478223166Skib{ 1479223166Skib struct lseek_args nuap; 1480223166Skib 1481223166Skib nuap.fd = uap->fd; 1482223166Skib nuap.offset = uap->offset; 1483223166Skib nuap.whence = uap->whence; 1484225617Skmacy return (sys_lseek(td, &nuap)); 1485223166Skib} 1486223166Skib#endif 1487223166Skib 1488223166Skibint 1489119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) 1490100384Speter{ 1491100384Speter int error; 1492100384Speter struct lseek_args ap; 1493100384Speter off_t pos; 1494100384Speter 1495107849Salfred ap.fd = uap->fd; 1496205014Snwhitehorn ap.offset = PAIR32TO64(off_t,uap->offset); 1497107849Salfred ap.whence = uap->whence; 1498225617Skmacy error = sys_lseek(td, &ap); 1499100384Speter /* Expand the quad return into two parts for eax and edx */ 1500100384Speter pos = *(off_t *)(td->td_retval); 1501205014Snwhitehorn td->td_retval[RETVAL_LO] = pos & 0xffffffff; /* %eax */ 1502205014Snwhitehorn td->td_retval[RETVAL_HI] = pos >> 32; /* %edx */ 1503100384Speter return error; 1504100384Speter} 1505100384Speter 1506100384Speterint 1507119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) 1508100384Speter{ 1509100384Speter struct truncate_args ap; 1510100384Speter 1511107849Salfred ap.path = uap->path; 1512205014Snwhitehorn ap.length = PAIR32TO64(off_t,uap->length); 1513225617Skmacy return (sys_truncate(td, &ap)); 1514100384Speter} 1515100384Speter 1516100384Speterint 1517119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 1518100384Speter{ 1519100384Speter struct ftruncate_args ap; 1520100384Speter 1521107849Salfred ap.fd = uap->fd; 1522205014Snwhitehorn ap.length = PAIR32TO64(off_t,uap->length); 1523225617Skmacy return (sys_ftruncate(td, &ap)); 1524100384Speter} 1525100384Speter 1526220238Skib#ifdef COMPAT_43 1527184183Sjhbint 1528220238Skibofreebsd32_getdirentries(struct thread *td, 1529220238Skib struct ofreebsd32_getdirentries_args *uap) 1530220238Skib{ 1531220238Skib struct ogetdirentries_args ap; 1532220238Skib int error; 1533220238Skib long loff; 1534220238Skib int32_t loff_cut; 1535220238Skib 1536220238Skib ap.fd = uap->fd; 1537220238Skib ap.buf = uap->buf; 1538220238Skib ap.count = uap->count; 1539220238Skib ap.basep = NULL; 1540220238Skib error = kern_ogetdirentries(td, &ap, &loff); 1541220238Skib if (error == 0) { 1542220238Skib loff_cut = loff; 1543220238Skib error = copyout(&loff_cut, uap->basep, sizeof(int32_t)); 1544220238Skib } 1545220238Skib return (error); 1546220238Skib} 1547220238Skib#endif 1548220238Skib 1549220238Skibint 1550184183Sjhbfreebsd32_getdirentries(struct thread *td, 1551184183Sjhb struct freebsd32_getdirentries_args *uap) 1552184183Sjhb{ 1553184183Sjhb long base; 1554184183Sjhb int32_t base32; 1555184183Sjhb int error; 1556184183Sjhb 1557184183Sjhb error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base); 1558184183Sjhb if (error) 1559184183Sjhb return (error); 1560184183Sjhb if (uap->basep != NULL) { 1561184183Sjhb base32 = base; 1562184183Sjhb error = copyout(&base32, uap->basep, sizeof(int32_t)); 1563184183Sjhb } 1564184183Sjhb return (error); 1565184183Sjhb} 1566184183Sjhb 1567171215Speter#ifdef COMPAT_FREEBSD6 1568171215Speter/* versions with the 'int pad' argument */ 1569171215Speterint 1570171215Speterfreebsd6_freebsd32_pread(struct thread *td, struct freebsd6_freebsd32_pread_args *uap) 1571171215Speter{ 1572171215Speter struct pread_args ap; 1573171215Speter 1574171215Speter ap.fd = uap->fd; 1575171215Speter ap.buf = uap->buf; 1576171215Speter ap.nbyte = uap->nbyte; 1577205014Snwhitehorn ap.offset = PAIR32TO64(off_t,uap->offset); 1578225617Skmacy return (sys_pread(td, &ap)); 1579171215Speter} 1580171215Speter 1581171215Speterint 1582171215Speterfreebsd6_freebsd32_pwrite(struct thread *td, struct freebsd6_freebsd32_pwrite_args *uap) 1583171215Speter{ 1584171215Speter struct pwrite_args ap; 1585171215Speter 1586171215Speter ap.fd = uap->fd; 1587171215Speter ap.buf = uap->buf; 1588171215Speter ap.nbyte = uap->nbyte; 1589205014Snwhitehorn ap.offset = PAIR32TO64(off_t,uap->offset); 1590225617Skmacy return (sys_pwrite(td, &ap)); 1591171215Speter} 1592171215Speter 1593171215Speterint 1594171215Speterfreebsd6_freebsd32_lseek(struct thread *td, struct freebsd6_freebsd32_lseek_args *uap) 1595171215Speter{ 1596171215Speter int error; 1597171215Speter struct lseek_args ap; 1598171215Speter off_t pos; 1599171215Speter 1600171215Speter ap.fd = uap->fd; 1601205014Snwhitehorn ap.offset = PAIR32TO64(off_t,uap->offset); 1602171215Speter ap.whence = uap->whence; 1603225617Skmacy error = sys_lseek(td, &ap); 1604171215Speter /* Expand the quad return into two parts for eax and edx */ 1605171215Speter pos = *(off_t *)(td->td_retval); 1606205014Snwhitehorn td->td_retval[RETVAL_LO] = pos & 0xffffffff; /* %eax */ 1607205014Snwhitehorn td->td_retval[RETVAL_HI] = pos >> 32; /* %edx */ 1608171215Speter return error; 1609171215Speter} 1610171215Speter 1611171215Speterint 1612171215Speterfreebsd6_freebsd32_truncate(struct thread *td, struct freebsd6_freebsd32_truncate_args *uap) 1613171215Speter{ 1614171215Speter struct truncate_args ap; 1615171215Speter 1616171215Speter ap.path = uap->path; 1617205014Snwhitehorn ap.length = PAIR32TO64(off_t,uap->length); 1618225617Skmacy return (sys_truncate(td, &ap)); 1619171215Speter} 1620171215Speter 1621171215Speterint 1622171215Speterfreebsd6_freebsd32_ftruncate(struct thread *td, struct freebsd6_freebsd32_ftruncate_args *uap) 1623171215Speter{ 1624171215Speter struct ftruncate_args ap; 1625171215Speter 1626171215Speter ap.fd = uap->fd; 1627205014Snwhitehorn ap.length = PAIR32TO64(off_t,uap->length); 1628225617Skmacy return (sys_ftruncate(td, &ap)); 1629171215Speter} 1630171215Speter#endif /* COMPAT_FREEBSD6 */ 1631171215Speter 1632156114Spsstruct sf_hdtr32 { 1633156114Sps uint32_t headers; 1634156114Sps int hdr_cnt; 1635156114Sps uint32_t trailers; 1636156114Sps int trl_cnt; 1637156114Sps}; 1638156114Sps 1639156114Spsstatic int 1640156114Spsfreebsd32_do_sendfile(struct thread *td, 1641156114Sps struct freebsd32_sendfile_args *uap, int compat) 1642104738Speter{ 1643156114Sps struct sendfile_args ap; 1644156114Sps struct sf_hdtr32 hdtr32; 1645156114Sps struct sf_hdtr hdtr; 1646156114Sps struct uio *hdr_uio, *trl_uio; 1647156114Sps struct iovec32 *iov32; 1648156114Sps int error; 1649104738Speter 1650156114Sps hdr_uio = trl_uio = NULL; 1651156114Sps 1652107849Salfred ap.fd = uap->fd; 1653107849Salfred ap.s = uap->s; 1654205014Snwhitehorn ap.offset = PAIR32TO64(off_t,uap->offset); 1655156114Sps ap.nbytes = uap->nbytes; 1656156114Sps ap.hdtr = (struct sf_hdtr *)uap->hdtr; /* XXX not used */ 1657156114Sps ap.sbytes = uap->sbytes; 1658107849Salfred ap.flags = uap->flags; 1659156114Sps 1660156114Sps if (uap->hdtr != NULL) { 1661156114Sps error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32)); 1662156114Sps if (error) 1663156114Sps goto out; 1664156114Sps PTRIN_CP(hdtr32, hdtr, headers); 1665156114Sps CP(hdtr32, hdtr, hdr_cnt); 1666156114Sps PTRIN_CP(hdtr32, hdtr, trailers); 1667156114Sps CP(hdtr32, hdtr, trl_cnt); 1668156114Sps 1669156114Sps if (hdtr.headers != NULL) { 1670160246Sjhb iov32 = PTRIN(hdtr32.headers); 1671156114Sps error = freebsd32_copyinuio(iov32, 1672156114Sps hdtr32.hdr_cnt, &hdr_uio); 1673156114Sps if (error) 1674156114Sps goto out; 1675156114Sps } 1676156114Sps if (hdtr.trailers != NULL) { 1677160246Sjhb iov32 = PTRIN(hdtr32.trailers); 1678156114Sps error = freebsd32_copyinuio(iov32, 1679156114Sps hdtr32.trl_cnt, &trl_uio); 1680156114Sps if (error) 1681156114Sps goto out; 1682156114Sps } 1683156114Sps } 1684156114Sps 1685156114Sps error = kern_sendfile(td, &ap, hdr_uio, trl_uio, compat); 1686156114Spsout: 1687156114Sps if (hdr_uio) 1688156114Sps free(hdr_uio, M_IOV); 1689156114Sps if (trl_uio) 1690156114Sps free(trl_uio, M_IOV); 1691156114Sps return (error); 1692104738Speter} 1693156114Sps 1694156114Sps#ifdef COMPAT_FREEBSD4 1695156114Spsint 1696156114Spsfreebsd4_freebsd32_sendfile(struct thread *td, 1697156114Sps struct freebsd4_freebsd32_sendfile_args *uap) 1698156114Sps{ 1699156114Sps return (freebsd32_do_sendfile(td, 1700156114Sps (struct freebsd32_sendfile_args *)uap, 1)); 1701156114Sps} 1702104738Speter#endif 1703104738Speter 1704104738Speterint 1705119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) 1706100384Speter{ 1707100384Speter 1708156114Sps return (freebsd32_do_sendfile(td, uap, 0)); 1709100384Speter} 1710100384Speter 1711100384Speterstatic void 1712210847Skibcopy_stat(struct stat *in, struct stat32 *out) 1713100384Speter{ 1714210847Skib 1715100384Speter CP(*in, *out, st_dev); 1716100384Speter CP(*in, *out, st_ino); 1717100384Speter CP(*in, *out, st_mode); 1718100384Speter CP(*in, *out, st_nlink); 1719100384Speter CP(*in, *out, st_uid); 1720100384Speter CP(*in, *out, st_gid); 1721100384Speter CP(*in, *out, st_rdev); 1722205792Sed TS_CP(*in, *out, st_atim); 1723205792Sed TS_CP(*in, *out, st_mtim); 1724205792Sed TS_CP(*in, *out, st_ctim); 1725100384Speter CP(*in, *out, st_size); 1726100384Speter CP(*in, *out, st_blocks); 1727100384Speter CP(*in, *out, st_blksize); 1728100384Speter CP(*in, *out, st_flags); 1729100384Speter CP(*in, *out, st_gen); 1730210848Skib TS_CP(*in, *out, st_birthtim); 1731100384Speter} 1732100384Speter 1733220238Skib#ifdef COMPAT_43 1734220238Skibstatic void 1735220238Skibcopy_ostat(struct stat *in, struct ostat32 *out) 1736220238Skib{ 1737220238Skib 1738220238Skib CP(*in, *out, st_dev); 1739220238Skib CP(*in, *out, st_ino); 1740220238Skib CP(*in, *out, st_mode); 1741220238Skib CP(*in, *out, st_nlink); 1742220238Skib CP(*in, *out, st_uid); 1743220238Skib CP(*in, *out, st_gid); 1744220238Skib CP(*in, *out, st_rdev); 1745220238Skib CP(*in, *out, st_size); 1746220238Skib TS_CP(*in, *out, st_atim); 1747220238Skib TS_CP(*in, *out, st_mtim); 1748220238Skib TS_CP(*in, *out, st_ctim); 1749220238Skib CP(*in, *out, st_blksize); 1750220238Skib CP(*in, *out, st_blocks); 1751220238Skib CP(*in, *out, st_flags); 1752220238Skib CP(*in, *out, st_gen); 1753220238Skib} 1754220238Skib#endif 1755220238Skib 1756100384Speterint 1757119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) 1758100384Speter{ 1759123746Speter struct stat sb; 1760123746Speter struct stat32 sb32; 1761100384Speter int error; 1762100384Speter 1763142059Sjhb error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 1764100384Speter if (error) 1765100384Speter return (error); 1766123746Speter copy_stat(&sb, &sb32); 1767123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1768100384Speter return (error); 1769100384Speter} 1770100384Speter 1771220238Skib#ifdef COMPAT_43 1772100384Speterint 1773220238Skibofreebsd32_stat(struct thread *td, struct ofreebsd32_stat_args *uap) 1774220238Skib{ 1775220238Skib struct stat sb; 1776220238Skib struct ostat32 sb32; 1777220238Skib int error; 1778220238Skib 1779220238Skib error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 1780220238Skib if (error) 1781220238Skib return (error); 1782220238Skib copy_ostat(&sb, &sb32); 1783220238Skib error = copyout(&sb32, uap->ub, sizeof (sb32)); 1784220238Skib return (error); 1785220238Skib} 1786220238Skib#endif 1787220238Skib 1788220238Skibint 1789119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) 1790100384Speter{ 1791123746Speter struct stat ub; 1792123746Speter struct stat32 ub32; 1793100384Speter int error; 1794100384Speter 1795142059Sjhb error = kern_fstat(td, uap->fd, &ub); 1796100384Speter if (error) 1797100384Speter return (error); 1798123746Speter copy_stat(&ub, &ub32); 1799123746Speter error = copyout(&ub32, uap->ub, sizeof(ub32)); 1800100384Speter return (error); 1801100384Speter} 1802100384Speter 1803220238Skib#ifdef COMPAT_43 1804100384Speterint 1805220238Skibofreebsd32_fstat(struct thread *td, struct ofreebsd32_fstat_args *uap) 1806220238Skib{ 1807220238Skib struct stat ub; 1808220238Skib struct ostat32 ub32; 1809220238Skib int error; 1810220238Skib 1811220238Skib error = kern_fstat(td, uap->fd, &ub); 1812220238Skib if (error) 1813220238Skib return (error); 1814220238Skib copy_ostat(&ub, &ub32); 1815220238Skib error = copyout(&ub32, uap->ub, sizeof(ub32)); 1816220238Skib return (error); 1817220238Skib} 1818220238Skib#endif 1819220238Skib 1820220238Skibint 1821177789Skibfreebsd32_fstatat(struct thread *td, struct freebsd32_fstatat_args *uap) 1822177789Skib{ 1823177789Skib struct stat ub; 1824177789Skib struct stat32 ub32; 1825177789Skib int error; 1826177789Skib 1827177789Skib error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE, &ub); 1828177789Skib if (error) 1829177789Skib return (error); 1830177789Skib copy_stat(&ub, &ub32); 1831177789Skib error = copyout(&ub32, uap->buf, sizeof(ub32)); 1832177789Skib return (error); 1833177789Skib} 1834177789Skib 1835177789Skibint 1836119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) 1837100384Speter{ 1838123746Speter struct stat sb; 1839123746Speter struct stat32 sb32; 1840142059Sjhb int error; 1841100384Speter 1842142059Sjhb error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 1843100384Speter if (error) 1844100384Speter return (error); 1845123746Speter copy_stat(&sb, &sb32); 1846123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1847100384Speter return (error); 1848100384Speter} 1849100384Speter 1850220238Skib#ifdef COMPAT_43 1851100384Speterint 1852220238Skibofreebsd32_lstat(struct thread *td, struct ofreebsd32_lstat_args *uap) 1853220238Skib{ 1854220238Skib struct stat sb; 1855220238Skib struct ostat32 sb32; 1856220238Skib int error; 1857220238Skib 1858220238Skib error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 1859220238Skib if (error) 1860220238Skib return (error); 1861220238Skib copy_ostat(&sb, &sb32); 1862220238Skib error = copyout(&sb32, uap->ub, sizeof (sb32)); 1863220238Skib return (error); 1864220238Skib} 1865220238Skib#endif 1866220238Skib 1867220238Skibint 1868119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) 1869100384Speter{ 1870100384Speter int error, name[CTL_MAXNAME]; 1871100384Speter size_t j, oldlen; 1872100384Speter 1873100384Speter if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1874100384Speter return (EINVAL); 1875136404Speter error = copyin(uap->name, name, uap->namelen * sizeof(int)); 1876100384Speter if (error) 1877100384Speter return (error); 1878100384Speter if (uap->oldlenp) 1879100384Speter oldlen = fuword32(uap->oldlenp); 1880100384Speter else 1881100384Speter oldlen = 0; 1882100384Speter error = userland_sysctl(td, name, uap->namelen, 1883100384Speter uap->old, &oldlen, 1, 1884136404Speter uap->new, uap->newlen, &j, SCTL_MASK32); 1885100384Speter if (error && error != ENOMEM) 1886186564Sed return (error); 1887136404Speter if (uap->oldlenp) 1888100384Speter suword32(uap->oldlenp, j); 1889186564Sed return (0); 1890100384Speter} 1891100384Speter 1892100384Speterint 1893185435Sbzfreebsd32_jail(struct thread *td, struct freebsd32_jail_args *uap) 1894185435Sbz{ 1895185435Sbz uint32_t version; 1896185435Sbz int error; 1897192895Sjamie struct jail j; 1898185435Sbz 1899185435Sbz error = copyin(uap->jail, &version, sizeof(uint32_t)); 1900185435Sbz if (error) 1901185435Sbz return (error); 1902190466Sjamie 1903185435Sbz switch (version) { 1904190466Sjamie case 0: 1905185435Sbz { 1906185435Sbz /* FreeBSD single IPv4 jails. */ 1907185435Sbz struct jail32_v0 j32_v0; 1908185435Sbz 1909192895Sjamie bzero(&j, sizeof(struct jail)); 1910185435Sbz error = copyin(uap->jail, &j32_v0, sizeof(struct jail32_v0)); 1911185435Sbz if (error) 1912185435Sbz return (error); 1913192895Sjamie CP(j32_v0, j, version); 1914192895Sjamie PTRIN_CP(j32_v0, j, path); 1915192895Sjamie PTRIN_CP(j32_v0, j, hostname); 1916192895Sjamie j.ip4s = j32_v0.ip_number; 1917185435Sbz break; 1918185435Sbz } 1919185435Sbz 1920185435Sbz case 1: 1921185435Sbz /* 1922185435Sbz * Version 1 was used by multi-IPv4 jail implementations 1923185435Sbz * that never made it into the official kernel. 1924185435Sbz */ 1925185435Sbz return (EINVAL); 1926185435Sbz 1927185435Sbz case 2: /* JAIL_API_VERSION */ 1928185435Sbz { 1929185435Sbz /* FreeBSD multi-IPv4/IPv6,noIP jails. */ 1930185435Sbz struct jail32 j32; 1931185435Sbz 1932185435Sbz error = copyin(uap->jail, &j32, sizeof(struct jail32)); 1933185435Sbz if (error) 1934185435Sbz return (error); 1935192895Sjamie CP(j32, j, version); 1936192895Sjamie PTRIN_CP(j32, j, path); 1937192895Sjamie PTRIN_CP(j32, j, hostname); 1938192895Sjamie PTRIN_CP(j32, j, jailname); 1939192895Sjamie CP(j32, j, ip4s); 1940192895Sjamie CP(j32, j, ip6s); 1941192895Sjamie PTRIN_CP(j32, j, ip4); 1942192895Sjamie PTRIN_CP(j32, j, ip6); 1943185435Sbz break; 1944185435Sbz } 1945185435Sbz 1946185435Sbz default: 1947185435Sbz /* Sci-Fi jails are not supported, sorry. */ 1948185435Sbz return (EINVAL); 1949185435Sbz } 1950192895Sjamie return (kern_jail(td, &j)); 1951185435Sbz} 1952185435Sbz 1953185435Sbzint 1954191673Sjamiefreebsd32_jail_set(struct thread *td, struct freebsd32_jail_set_args *uap) 1955191673Sjamie{ 1956191673Sjamie struct uio *auio; 1957191673Sjamie int error; 1958191673Sjamie 1959191673Sjamie /* Check that we have an even number of iovecs. */ 1960191673Sjamie if (uap->iovcnt & 1) 1961191673Sjamie return (EINVAL); 1962191673Sjamie 1963191673Sjamie error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 1964191673Sjamie if (error) 1965191673Sjamie return (error); 1966191673Sjamie error = kern_jail_set(td, auio, uap->flags); 1967191673Sjamie free(auio, M_IOV); 1968191673Sjamie return (error); 1969191673Sjamie} 1970191673Sjamie 1971191673Sjamieint 1972191673Sjamiefreebsd32_jail_get(struct thread *td, struct freebsd32_jail_get_args *uap) 1973191673Sjamie{ 1974191673Sjamie struct iovec32 iov32; 1975191673Sjamie struct uio *auio; 1976191673Sjamie int error, i; 1977191673Sjamie 1978191673Sjamie /* Check that we have an even number of iovecs. */ 1979191673Sjamie if (uap->iovcnt & 1) 1980191673Sjamie return (EINVAL); 1981191673Sjamie 1982191673Sjamie error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 1983191673Sjamie if (error) 1984191673Sjamie return (error); 1985191673Sjamie error = kern_jail_get(td, auio, uap->flags); 1986191673Sjamie if (error == 0) 1987191673Sjamie for (i = 0; i < uap->iovcnt; i++) { 1988191673Sjamie PTROUT_CP(auio->uio_iov[i], iov32, iov_base); 1989191673Sjamie CP(auio->uio_iov[i], iov32, iov_len); 1990191673Sjamie error = copyout(&iov32, uap->iovp + i, sizeof(iov32)); 1991191673Sjamie if (error != 0) 1992191673Sjamie break; 1993191673Sjamie } 1994191673Sjamie free(auio, M_IOV); 1995191673Sjamie return (error); 1996191673Sjamie} 1997191673Sjamie 1998191673Sjamieint 1999119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) 2000100384Speter{ 2001113859Sjhb struct sigaction32 s32; 2002113859Sjhb struct sigaction sa, osa, *sap; 2003100384Speter int error; 2004100384Speter 2005113859Sjhb if (uap->act) { 2006113859Sjhb error = copyin(uap->act, &s32, sizeof(s32)); 2007100384Speter if (error) 2008100384Speter return (error); 2009113859Sjhb sa.sa_handler = PTRIN(s32.sa_u); 2010113859Sjhb CP(s32, sa, sa_flags); 2011113859Sjhb CP(s32, sa, sa_mask); 2012113859Sjhb sap = &sa; 2013113859Sjhb } else 2014113859Sjhb sap = NULL; 2015113859Sjhb error = kern_sigaction(td, uap->sig, sap, &osa, 0); 2016146583Sps if (error == 0 && uap->oact != NULL) { 2017113859Sjhb s32.sa_u = PTROUT(osa.sa_handler); 2018113859Sjhb CP(osa, s32, sa_flags); 2019113859Sjhb CP(osa, s32, sa_mask); 2020113859Sjhb error = copyout(&s32, uap->oact, sizeof(s32)); 2021100384Speter } 2022100384Speter return (error); 2023100384Speter} 2024100384Speter 2025114987Speter#ifdef COMPAT_FREEBSD4 2026114987Speterint 2027119333Speterfreebsd4_freebsd32_sigaction(struct thread *td, 2028119333Speter struct freebsd4_freebsd32_sigaction_args *uap) 2029114987Speter{ 2030114987Speter struct sigaction32 s32; 2031114987Speter struct sigaction sa, osa, *sap; 2032114987Speter int error; 2033114987Speter 2034114987Speter if (uap->act) { 2035114987Speter error = copyin(uap->act, &s32, sizeof(s32)); 2036114987Speter if (error) 2037114987Speter return (error); 2038114987Speter sa.sa_handler = PTRIN(s32.sa_u); 2039114987Speter CP(s32, sa, sa_flags); 2040114987Speter CP(s32, sa, sa_mask); 2041114987Speter sap = &sa; 2042114987Speter } else 2043114987Speter sap = NULL; 2044114987Speter error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 2045146583Sps if (error == 0 && uap->oact != NULL) { 2046114987Speter s32.sa_u = PTROUT(osa.sa_handler); 2047114987Speter CP(osa, s32, sa_flags); 2048114987Speter CP(osa, s32, sa_mask); 2049114987Speter error = copyout(&s32, uap->oact, sizeof(s32)); 2050114987Speter } 2051114987Speter return (error); 2052114987Speter} 2053114987Speter#endif 2054114987Speter 2055151582Sps#ifdef COMPAT_43 2056151720Speterstruct osigaction32 { 2057151582Sps u_int32_t sa_u; 2058151582Sps osigset_t sa_mask; 2059151582Sps int sa_flags; 2060151582Sps}; 2061151582Sps 2062151582Sps#define ONSIG 32 2063151582Sps 2064140481Spsint 2065151720Speterofreebsd32_sigaction(struct thread *td, 2066151720Speter struct ofreebsd32_sigaction_args *uap) 2067151582Sps{ 2068151720Speter struct osigaction32 s32; 2069151582Sps struct sigaction sa, osa, *sap; 2070151582Sps int error; 2071151582Sps 2072151582Sps if (uap->signum <= 0 || uap->signum >= ONSIG) 2073151582Sps return (EINVAL); 2074151582Sps 2075151582Sps if (uap->nsa) { 2076151582Sps error = copyin(uap->nsa, &s32, sizeof(s32)); 2077151582Sps if (error) 2078151582Sps return (error); 2079151582Sps sa.sa_handler = PTRIN(s32.sa_u); 2080151582Sps CP(s32, sa, sa_flags); 2081151582Sps OSIG2SIG(s32.sa_mask, sa.sa_mask); 2082151582Sps sap = &sa; 2083151582Sps } else 2084151582Sps sap = NULL; 2085151582Sps error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET); 2086151582Sps if (error == 0 && uap->osa != NULL) { 2087151582Sps s32.sa_u = PTROUT(osa.sa_handler); 2088151582Sps CP(osa, s32, sa_flags); 2089151582Sps SIG2OSIG(osa.sa_mask, s32.sa_mask); 2090151582Sps error = copyout(&s32, uap->osa, sizeof(s32)); 2091151582Sps } 2092151582Sps return (error); 2093151582Sps} 2094151582Sps 2095151582Spsint 2096151720Speterofreebsd32_sigprocmask(struct thread *td, 2097151720Speter struct ofreebsd32_sigprocmask_args *uap) 2098151582Sps{ 2099151582Sps sigset_t set, oset; 2100151582Sps int error; 2101151582Sps 2102151582Sps OSIG2SIG(uap->mask, set); 2103198507Skib error = kern_sigprocmask(td, uap->how, &set, &oset, SIGPROCMASK_OLD); 2104151582Sps SIG2OSIG(oset, td->td_retval[0]); 2105151582Sps return (error); 2106151582Sps} 2107151582Sps 2108151582Spsint 2109151720Speterofreebsd32_sigpending(struct thread *td, 2110151720Speter struct ofreebsd32_sigpending_args *uap) 2111151582Sps{ 2112151582Sps struct proc *p = td->td_proc; 2113151582Sps sigset_t siglist; 2114151582Sps 2115151582Sps PROC_LOCK(p); 2116151582Sps siglist = p->p_siglist; 2117151582Sps SIGSETOR(siglist, td->td_siglist); 2118151582Sps PROC_UNLOCK(p); 2119151582Sps SIG2OSIG(siglist, td->td_retval[0]); 2120151582Sps return (0); 2121151582Sps} 2122151582Sps 2123151582Spsstruct sigvec32 { 2124151582Sps u_int32_t sv_handler; 2125151582Sps int sv_mask; 2126151582Sps int sv_flags; 2127151582Sps}; 2128151582Sps 2129151582Spsint 2130151720Speterofreebsd32_sigvec(struct thread *td, 2131151720Speter struct ofreebsd32_sigvec_args *uap) 2132151582Sps{ 2133151582Sps struct sigvec32 vec; 2134151582Sps struct sigaction sa, osa, *sap; 2135151582Sps int error; 2136151582Sps 2137151582Sps if (uap->signum <= 0 || uap->signum >= ONSIG) 2138151582Sps return (EINVAL); 2139151582Sps 2140151582Sps if (uap->nsv) { 2141151582Sps error = copyin(uap->nsv, &vec, sizeof(vec)); 2142151582Sps if (error) 2143151582Sps return (error); 2144151582Sps sa.sa_handler = PTRIN(vec.sv_handler); 2145151582Sps OSIG2SIG(vec.sv_mask, sa.sa_mask); 2146151582Sps sa.sa_flags = vec.sv_flags; 2147151582Sps sa.sa_flags ^= SA_RESTART; 2148151582Sps sap = &sa; 2149151582Sps } else 2150151582Sps sap = NULL; 2151151582Sps error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET); 2152151582Sps if (error == 0 && uap->osv != NULL) { 2153151582Sps vec.sv_handler = PTROUT(osa.sa_handler); 2154151582Sps SIG2OSIG(osa.sa_mask, vec.sv_mask); 2155151582Sps vec.sv_flags = osa.sa_flags; 2156151582Sps vec.sv_flags &= ~SA_NOCLDWAIT; 2157151582Sps vec.sv_flags ^= SA_RESTART; 2158151582Sps error = copyout(&vec, uap->osv, sizeof(vec)); 2159151582Sps } 2160151582Sps return (error); 2161151582Sps} 2162151582Sps 2163151582Spsint 2164151720Speterofreebsd32_sigblock(struct thread *td, 2165151720Speter struct ofreebsd32_sigblock_args *uap) 2166151582Sps{ 2167198507Skib sigset_t set, oset; 2168151582Sps 2169151582Sps OSIG2SIG(uap->mask, set); 2170198507Skib kern_sigprocmask(td, SIG_BLOCK, &set, &oset, 0); 2171198507Skib SIG2OSIG(oset, td->td_retval[0]); 2172151582Sps return (0); 2173151582Sps} 2174151582Sps 2175151582Spsint 2176151720Speterofreebsd32_sigsetmask(struct thread *td, 2177151720Speter struct ofreebsd32_sigsetmask_args *uap) 2178151582Sps{ 2179198507Skib sigset_t set, oset; 2180151582Sps 2181151582Sps OSIG2SIG(uap->mask, set); 2182198507Skib kern_sigprocmask(td, SIG_SETMASK, &set, &oset, 0); 2183198507Skib SIG2OSIG(oset, td->td_retval[0]); 2184151582Sps return (0); 2185151582Sps} 2186151582Sps 2187151582Spsint 2188151720Speterofreebsd32_sigsuspend(struct thread *td, 2189151720Speter struct ofreebsd32_sigsuspend_args *uap) 2190151582Sps{ 2191151582Sps sigset_t mask; 2192151582Sps 2193151582Sps OSIG2SIG(uap->mask, mask); 2194198506Skib return (kern_sigsuspend(td, mask)); 2195151582Sps} 2196151582Sps 2197151582Spsstruct sigstack32 { 2198151582Sps u_int32_t ss_sp; 2199151582Sps int ss_onstack; 2200151582Sps}; 2201151582Sps 2202151582Spsint 2203151720Speterofreebsd32_sigstack(struct thread *td, 2204151720Speter struct ofreebsd32_sigstack_args *uap) 2205151582Sps{ 2206151582Sps struct sigstack32 s32; 2207151582Sps struct sigstack nss, oss; 2208170870Smjacob int error = 0, unss; 2209151582Sps 2210151582Sps if (uap->nss != NULL) { 2211151582Sps error = copyin(uap->nss, &s32, sizeof(s32)); 2212151582Sps if (error) 2213151582Sps return (error); 2214151582Sps nss.ss_sp = PTRIN(s32.ss_sp); 2215151582Sps CP(s32, nss, ss_onstack); 2216170870Smjacob unss = 1; 2217170870Smjacob } else { 2218170870Smjacob unss = 0; 2219151582Sps } 2220151582Sps oss.ss_sp = td->td_sigstk.ss_sp; 2221151582Sps oss.ss_onstack = sigonstack(cpu_getstack(td)); 2222170870Smjacob if (unss) { 2223151582Sps td->td_sigstk.ss_sp = nss.ss_sp; 2224151582Sps td->td_sigstk.ss_size = 0; 2225170870Smjacob td->td_sigstk.ss_flags |= (nss.ss_onstack & SS_ONSTACK); 2226151582Sps td->td_pflags |= TDP_ALTSTACK; 2227151582Sps } 2228151582Sps if (uap->oss != NULL) { 2229151582Sps s32.ss_sp = PTROUT(oss.ss_sp); 2230151582Sps CP(oss, s32, ss_onstack); 2231151582Sps error = copyout(&s32, uap->oss, sizeof(s32)); 2232151582Sps } 2233151582Sps return (error); 2234151582Sps} 2235151582Sps#endif 2236151582Sps 2237151582Spsint 2238140481Spsfreebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap) 2239140481Sps{ 2240140481Sps struct timespec32 rmt32, rqt32; 2241140481Sps struct timespec rmt, rqt; 2242140481Sps int error; 2243140481Sps 2244151355Sps error = copyin(uap->rqtp, &rqt32, sizeof(rqt32)); 2245140481Sps if (error) 2246140481Sps return (error); 2247140481Sps 2248140481Sps CP(rqt32, rqt, tv_sec); 2249140481Sps CP(rqt32, rqt, tv_nsec); 2250140481Sps 2251140481Sps if (uap->rmtp && 2252140481Sps !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) 2253140481Sps return (EFAULT); 2254140481Sps error = kern_nanosleep(td, &rqt, &rmt); 2255140481Sps if (error && uap->rmtp) { 2256140481Sps int error2; 2257140481Sps 2258140481Sps CP(rmt, rmt32, tv_sec); 2259140481Sps CP(rmt, rmt32, tv_nsec); 2260140481Sps 2261151355Sps error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt32)); 2262140481Sps if (error2) 2263140481Sps error = error2; 2264140481Sps } 2265140481Sps return (error); 2266140481Sps} 2267140481Sps 2268151357Spsint 2269151357Spsfreebsd32_clock_gettime(struct thread *td, 2270151357Sps struct freebsd32_clock_gettime_args *uap) 2271151357Sps{ 2272151357Sps struct timespec ats; 2273151357Sps struct timespec32 ats32; 2274151357Sps int error; 2275151357Sps 2276151357Sps error = kern_clock_gettime(td, uap->clock_id, &ats); 2277151357Sps if (error == 0) { 2278151357Sps CP(ats, ats32, tv_sec); 2279151357Sps CP(ats, ats32, tv_nsec); 2280151357Sps error = copyout(&ats32, uap->tp, sizeof(ats32)); 2281151357Sps } 2282151357Sps return (error); 2283151357Sps} 2284151357Sps 2285151357Spsint 2286151357Spsfreebsd32_clock_settime(struct thread *td, 2287151357Sps struct freebsd32_clock_settime_args *uap) 2288151357Sps{ 2289151357Sps struct timespec ats; 2290151357Sps struct timespec32 ats32; 2291151357Sps int error; 2292151357Sps 2293151357Sps error = copyin(uap->tp, &ats32, sizeof(ats32)); 2294151357Sps if (error) 2295151357Sps return (error); 2296151357Sps CP(ats32, ats, tv_sec); 2297151357Sps CP(ats32, ats, tv_nsec); 2298151357Sps 2299151357Sps return (kern_clock_settime(td, uap->clock_id, &ats)); 2300151357Sps} 2301151357Sps 2302151357Spsint 2303151357Spsfreebsd32_clock_getres(struct thread *td, 2304151357Sps struct freebsd32_clock_getres_args *uap) 2305151357Sps{ 2306151357Sps struct timespec ts; 2307151357Sps struct timespec32 ts32; 2308151357Sps int error; 2309151357Sps 2310151357Sps if (uap->tp == NULL) 2311151357Sps return (0); 2312151357Sps error = kern_clock_getres(td, uap->clock_id, &ts); 2313151357Sps if (error == 0) { 2314151357Sps CP(ts, ts32, tv_sec); 2315151357Sps CP(ts, ts32, tv_nsec); 2316151357Sps error = copyout(&ts32, uap->tp, sizeof(ts32)); 2317151357Sps } 2318151357Sps return (error); 2319151357Sps} 2320151357Sps 2321162551Sdavidxuint 2322162551Sdavidxufreebsd32_thr_new(struct thread *td, 2323162551Sdavidxu struct freebsd32_thr_new_args *uap) 2324162551Sdavidxu{ 2325162551Sdavidxu struct thr_param32 param32; 2326162551Sdavidxu struct thr_param param; 2327162551Sdavidxu int error; 2328162551Sdavidxu 2329162551Sdavidxu if (uap->param_size < 0 || 2330162551Sdavidxu uap->param_size > sizeof(struct thr_param32)) 2331162551Sdavidxu return (EINVAL); 2332162551Sdavidxu bzero(¶m, sizeof(struct thr_param)); 2333162551Sdavidxu bzero(¶m32, sizeof(struct thr_param32)); 2334162551Sdavidxu error = copyin(uap->param, ¶m32, uap->param_size); 2335162551Sdavidxu if (error != 0) 2336162551Sdavidxu return (error); 2337162551Sdavidxu param.start_func = PTRIN(param32.start_func); 2338162551Sdavidxu param.arg = PTRIN(param32.arg); 2339162551Sdavidxu param.stack_base = PTRIN(param32.stack_base); 2340162551Sdavidxu param.stack_size = param32.stack_size; 2341162551Sdavidxu param.tls_base = PTRIN(param32.tls_base); 2342162551Sdavidxu param.tls_size = param32.tls_size; 2343162551Sdavidxu param.child_tid = PTRIN(param32.child_tid); 2344162551Sdavidxu param.parent_tid = PTRIN(param32.parent_tid); 2345162551Sdavidxu param.flags = param32.flags; 2346162551Sdavidxu param.rtp = PTRIN(param32.rtp); 2347162551Sdavidxu param.spare[0] = PTRIN(param32.spare[0]); 2348162551Sdavidxu param.spare[1] = PTRIN(param32.spare[1]); 2349162551Sdavidxu param.spare[2] = PTRIN(param32.spare[2]); 2350162551Sdavidxu 2351162551Sdavidxu return (kern_thr_new(td, ¶m)); 2352162551Sdavidxu} 2353162551Sdavidxu 2354162551Sdavidxuint 2355162551Sdavidxufreebsd32_thr_suspend(struct thread *td, struct freebsd32_thr_suspend_args *uap) 2356162551Sdavidxu{ 2357162551Sdavidxu struct timespec32 ts32; 2358162551Sdavidxu struct timespec ts, *tsp; 2359162551Sdavidxu int error; 2360162551Sdavidxu 2361162551Sdavidxu error = 0; 2362162551Sdavidxu tsp = NULL; 2363162551Sdavidxu if (uap->timeout != NULL) { 2364162551Sdavidxu error = copyin((const void *)uap->timeout, (void *)&ts32, 2365162551Sdavidxu sizeof(struct timespec32)); 2366162551Sdavidxu if (error != 0) 2367162551Sdavidxu return (error); 2368162551Sdavidxu ts.tv_sec = ts32.tv_sec; 2369162551Sdavidxu ts.tv_nsec = ts32.tv_nsec; 2370162551Sdavidxu tsp = &ts; 2371162551Sdavidxu } 2372162551Sdavidxu return (kern_thr_suspend(td, tsp)); 2373162551Sdavidxu} 2374162551Sdavidxu 2375163018Sdavidxuvoid 2376209687Skibsiginfo_to_siginfo32(const siginfo_t *src, struct siginfo32 *dst) 2377163018Sdavidxu{ 2378163018Sdavidxu bzero(dst, sizeof(*dst)); 2379163018Sdavidxu dst->si_signo = src->si_signo; 2380163018Sdavidxu dst->si_errno = src->si_errno; 2381163018Sdavidxu dst->si_code = src->si_code; 2382163018Sdavidxu dst->si_pid = src->si_pid; 2383163018Sdavidxu dst->si_uid = src->si_uid; 2384163018Sdavidxu dst->si_status = src->si_status; 2385184829Speter dst->si_addr = (uintptr_t)src->si_addr; 2386163018Sdavidxu dst->si_value.sigval_int = src->si_value.sival_int; 2387163018Sdavidxu dst->si_timerid = src->si_timerid; 2388163018Sdavidxu dst->si_overrun = src->si_overrun; 2389163018Sdavidxu} 2390163018Sdavidxu 2391163018Sdavidxuint 2392163018Sdavidxufreebsd32_sigtimedwait(struct thread *td, struct freebsd32_sigtimedwait_args *uap) 2393163018Sdavidxu{ 2394163018Sdavidxu struct timespec32 ts32; 2395163018Sdavidxu struct timespec ts; 2396163018Sdavidxu struct timespec *timeout; 2397163018Sdavidxu sigset_t set; 2398163018Sdavidxu ksiginfo_t ksi; 2399163018Sdavidxu struct siginfo32 si32; 2400163018Sdavidxu int error; 2401163018Sdavidxu 2402163018Sdavidxu if (uap->timeout) { 2403163018Sdavidxu error = copyin(uap->timeout, &ts32, sizeof(ts32)); 2404163018Sdavidxu if (error) 2405163018Sdavidxu return (error); 2406163018Sdavidxu ts.tv_sec = ts32.tv_sec; 2407163018Sdavidxu ts.tv_nsec = ts32.tv_nsec; 2408163018Sdavidxu timeout = &ts; 2409163018Sdavidxu } else 2410163018Sdavidxu timeout = NULL; 2411163018Sdavidxu 2412163018Sdavidxu error = copyin(uap->set, &set, sizeof(set)); 2413163018Sdavidxu if (error) 2414163018Sdavidxu return (error); 2415163018Sdavidxu 2416163018Sdavidxu error = kern_sigtimedwait(td, set, &ksi, timeout); 2417163018Sdavidxu if (error) 2418163018Sdavidxu return (error); 2419163018Sdavidxu 2420163018Sdavidxu if (uap->info) { 2421163018Sdavidxu siginfo_to_siginfo32(&ksi.ksi_info, &si32); 2422163018Sdavidxu error = copyout(&si32, uap->info, sizeof(struct siginfo32)); 2423163018Sdavidxu } 2424163018Sdavidxu 2425163018Sdavidxu if (error == 0) 2426163018Sdavidxu td->td_retval[0] = ksi.ksi_signo; 2427163018Sdavidxu return (error); 2428163018Sdavidxu} 2429163018Sdavidxu 2430163018Sdavidxu/* 2431163018Sdavidxu * MPSAFE 2432163018Sdavidxu */ 2433163018Sdavidxuint 2434163018Sdavidxufreebsd32_sigwaitinfo(struct thread *td, struct freebsd32_sigwaitinfo_args *uap) 2435163018Sdavidxu{ 2436163018Sdavidxu ksiginfo_t ksi; 2437163018Sdavidxu struct siginfo32 si32; 2438163018Sdavidxu sigset_t set; 2439163018Sdavidxu int error; 2440163018Sdavidxu 2441163018Sdavidxu error = copyin(uap->set, &set, sizeof(set)); 2442163018Sdavidxu if (error) 2443163018Sdavidxu return (error); 2444163018Sdavidxu 2445163018Sdavidxu error = kern_sigtimedwait(td, set, &ksi, NULL); 2446163018Sdavidxu if (error) 2447163018Sdavidxu return (error); 2448163018Sdavidxu 2449163018Sdavidxu if (uap->info) { 2450163018Sdavidxu siginfo_to_siginfo32(&ksi.ksi_info, &si32); 2451163018Sdavidxu error = copyout(&si32, uap->info, sizeof(struct siginfo32)); 2452163018Sdavidxu } 2453163018Sdavidxu if (error == 0) 2454163018Sdavidxu td->td_retval[0] = ksi.ksi_signo; 2455163018Sdavidxu return (error); 2456163018Sdavidxu} 2457163018Sdavidxu 2458180433Sbrooksint 2459180433Sbrooksfreebsd32_cpuset_setid(struct thread *td, 2460180433Sbrooks struct freebsd32_cpuset_setid_args *uap) 2461180433Sbrooks{ 2462180433Sbrooks struct cpuset_setid_args ap; 2463180433Sbrooks 2464180433Sbrooks ap.which = uap->which; 2465205014Snwhitehorn ap.id = PAIR32TO64(id_t,uap->id); 2466180433Sbrooks ap.setid = uap->setid; 2467180433Sbrooks 2468225617Skmacy return (sys_cpuset_setid(td, &ap)); 2469180433Sbrooks} 2470180433Sbrooks 2471180433Sbrooksint 2472180433Sbrooksfreebsd32_cpuset_getid(struct thread *td, 2473180433Sbrooks struct freebsd32_cpuset_getid_args *uap) 2474180433Sbrooks{ 2475180433Sbrooks struct cpuset_getid_args ap; 2476180433Sbrooks 2477180433Sbrooks ap.level = uap->level; 2478180433Sbrooks ap.which = uap->which; 2479205014Snwhitehorn ap.id = PAIR32TO64(id_t,uap->id); 2480180433Sbrooks ap.setid = uap->setid; 2481180433Sbrooks 2482225617Skmacy return (sys_cpuset_getid(td, &ap)); 2483180433Sbrooks} 2484180433Sbrooks 2485180433Sbrooksint 2486180433Sbrooksfreebsd32_cpuset_getaffinity(struct thread *td, 2487180433Sbrooks struct freebsd32_cpuset_getaffinity_args *uap) 2488180433Sbrooks{ 2489180433Sbrooks struct cpuset_getaffinity_args ap; 2490180433Sbrooks 2491180433Sbrooks ap.level = uap->level; 2492180433Sbrooks ap.which = uap->which; 2493205014Snwhitehorn ap.id = PAIR32TO64(id_t,uap->id); 2494180433Sbrooks ap.cpusetsize = uap->cpusetsize; 2495180433Sbrooks ap.mask = uap->mask; 2496180433Sbrooks 2497225617Skmacy return (sys_cpuset_getaffinity(td, &ap)); 2498180433Sbrooks} 2499180433Sbrooks 2500180433Sbrooksint 2501180433Sbrooksfreebsd32_cpuset_setaffinity(struct thread *td, 2502180433Sbrooks struct freebsd32_cpuset_setaffinity_args *uap) 2503180433Sbrooks{ 2504180433Sbrooks struct cpuset_setaffinity_args ap; 2505180433Sbrooks 2506180433Sbrooks ap.level = uap->level; 2507180433Sbrooks ap.which = uap->which; 2508205014Snwhitehorn ap.id = PAIR32TO64(id_t,uap->id); 2509180433Sbrooks ap.cpusetsize = uap->cpusetsize; 2510180433Sbrooks ap.mask = uap->mask; 2511180433Sbrooks 2512225617Skmacy return (sys_cpuset_setaffinity(td, &ap)); 2513180433Sbrooks} 2514180433Sbrooks 2515183188Sobrienint 2516183188Sobrienfreebsd32_nmount(struct thread *td, 2517183188Sobrien struct freebsd32_nmount_args /* { 2518183188Sobrien struct iovec *iovp; 2519183188Sobrien unsigned int iovcnt; 2520183188Sobrien int flags; 2521183188Sobrien } */ *uap) 2522183188Sobrien{ 2523183188Sobrien struct uio *auio; 2524230725Smckusick uint64_t flags; 2525189290Sjamie int error; 2526183188Sobrien 2527230725Smckusick /* 2528230725Smckusick * Mount flags are now 64-bits. On 32-bit archtectures only 2529230725Smckusick * 32-bits are passed in, but from here on everything handles 2530230725Smckusick * 64-bit flags correctly. 2531230725Smckusick */ 2532230725Smckusick flags = uap->flags; 2533183188Sobrien 2534230725Smckusick AUDIT_ARG_FFLAGS(flags); 2535230725Smckusick 2536183188Sobrien /* 2537183188Sobrien * Filter out MNT_ROOTFS. We do not want clients of nmount() in 2538183188Sobrien * userspace to set this flag, but we must filter it out if we want 2539183188Sobrien * MNT_UPDATE on the root file system to work. 2540215747Spluknet * MNT_ROOTFS should only be set by the kernel when mounting its 2541215747Spluknet * root file system. 2542183188Sobrien */ 2543230725Smckusick flags &= ~MNT_ROOTFS; 2544183188Sobrien 2545183188Sobrien /* 2546183188Sobrien * check that we have an even number of iovec's 2547183188Sobrien * and that we have at least two options. 2548183188Sobrien */ 2549183188Sobrien if ((uap->iovcnt & 1) || (uap->iovcnt < 4)) 2550183188Sobrien return (EINVAL); 2551183188Sobrien 2552183188Sobrien error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 2553183188Sobrien if (error) 2554183188Sobrien return (error); 2555230725Smckusick error = vfs_donmount(td, flags, auio); 2556183188Sobrien 2557183188Sobrien free(auio, M_IOV); 2558183188Sobrien return error; 2559183188Sobrien} 2560183188Sobrien 2561100384Speter#if 0 2562100384Speterint 2563119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) 2564100384Speter{ 2565100384Speter struct yyy32 *p32, s32; 2566100384Speter struct yyy *p = NULL, s; 2567183044Sobrien struct xxx_arg ap; 2568183044Sobrien int error; 2569100384Speter 2570147654Sjhb if (uap->zzz) { 2571147654Sjhb error = copyin(uap->zzz, &s32, sizeof(s32)); 2572100384Speter if (error) 2573100384Speter return (error); 2574100384Speter /* translate in */ 2575147654Sjhb p = &s; 2576100384Speter } 2577147654Sjhb error = kern_xxx(td, p); 2578100384Speter if (error) 2579100384Speter return (error); 2580147654Sjhb if (uap->zzz) { 2581100384Speter /* translate out */ 2582100384Speter error = copyout(&s32, p32, sizeof(s32)); 2583100384Speter } 2584100384Speter return (error); 2585100384Speter} 2586100384Speter#endif 2587183365Sjhb 2588183365Sjhbint 2589183365Sjhbsyscall32_register(int *offset, struct sysent *new_sysent, 2590183365Sjhb struct sysent *old_sysent) 2591183365Sjhb{ 2592183365Sjhb if (*offset == NO_SYSCALL) { 2593183365Sjhb int i; 2594183365Sjhb 2595183365Sjhb for (i = 1; i < SYS_MAXSYSCALL; ++i) 2596183365Sjhb if (freebsd32_sysent[i].sy_call == 2597183365Sjhb (sy_call_t *)lkmnosys) 2598183365Sjhb break; 2599183365Sjhb if (i == SYS_MAXSYSCALL) 2600183365Sjhb return (ENFILE); 2601183365Sjhb *offset = i; 2602183365Sjhb } else if (*offset < 0 || *offset >= SYS_MAXSYSCALL) 2603183365Sjhb return (EINVAL); 2604183365Sjhb else if (freebsd32_sysent[*offset].sy_call != (sy_call_t *)lkmnosys && 2605183365Sjhb freebsd32_sysent[*offset].sy_call != (sy_call_t *)lkmressys) 2606183365Sjhb return (EEXIST); 2607183365Sjhb 2608183365Sjhb *old_sysent = freebsd32_sysent[*offset]; 2609183365Sjhb freebsd32_sysent[*offset] = *new_sysent; 2610183365Sjhb return 0; 2611183365Sjhb} 2612183365Sjhb 2613183365Sjhbint 2614183365Sjhbsyscall32_deregister(int *offset, struct sysent *old_sysent) 2615183365Sjhb{ 2616183365Sjhb 2617183365Sjhb if (*offset) 2618183365Sjhb freebsd32_sysent[*offset] = *old_sysent; 2619183365Sjhb return 0; 2620183365Sjhb} 2621183365Sjhb 2622183365Sjhbint 2623183365Sjhbsyscall32_module_handler(struct module *mod, int what, void *arg) 2624183365Sjhb{ 2625183365Sjhb struct syscall_module_data *data = (struct syscall_module_data*)arg; 2626183365Sjhb modspecific_t ms; 2627183365Sjhb int error; 2628183365Sjhb 2629183365Sjhb switch (what) { 2630183365Sjhb case MOD_LOAD: 2631183365Sjhb error = syscall32_register(data->offset, data->new_sysent, 2632183365Sjhb &data->old_sysent); 2633183365Sjhb if (error) { 2634183365Sjhb /* Leave a mark so we know to safely unload below. */ 2635183365Sjhb data->offset = NULL; 2636183365Sjhb return error; 2637183365Sjhb } 2638183365Sjhb ms.intval = *data->offset; 2639183365Sjhb MOD_XLOCK; 2640183365Sjhb module_setspecific(mod, &ms); 2641183365Sjhb MOD_XUNLOCK; 2642183365Sjhb if (data->chainevh) 2643183365Sjhb error = data->chainevh(mod, what, data->chainarg); 2644183365Sjhb return (error); 2645183365Sjhb case MOD_UNLOAD: 2646183365Sjhb /* 2647183365Sjhb * MOD_LOAD failed, so just return without calling the 2648183365Sjhb * chained handler since we didn't pass along the MOD_LOAD 2649183365Sjhb * event. 2650183365Sjhb */ 2651183365Sjhb if (data->offset == NULL) 2652183365Sjhb return (0); 2653183365Sjhb if (data->chainevh) { 2654183365Sjhb error = data->chainevh(mod, what, data->chainarg); 2655183365Sjhb if (error) 2656183365Sjhb return (error); 2657183365Sjhb } 2658185589Sjhb error = syscall32_deregister(data->offset, &data->old_sysent); 2659183365Sjhb return (error); 2660183365Sjhb default: 2661183365Sjhb error = EOPNOTSUPP; 2662183365Sjhb if (data->chainevh) 2663183365Sjhb error = data->chainevh(mod, what, data->chainarg); 2664183365Sjhb return (error); 2665183365Sjhb } 2666183365Sjhb} 2667205014Snwhitehorn 2668205321Skibint 2669205321Skibsyscall32_helper_register(struct syscall_helper_data *sd) 2670205321Skib{ 2671205321Skib struct syscall_helper_data *sd1; 2672205321Skib int error; 2673205321Skib 2674205321Skib for (sd1 = sd; sd1->syscall_no != NO_SYSCALL; sd1++) { 2675205321Skib error = syscall32_register(&sd1->syscall_no, &sd1->new_sysent, 2676205321Skib &sd1->old_sysent); 2677205321Skib if (error != 0) { 2678205321Skib syscall32_helper_unregister(sd); 2679205321Skib return (error); 2680205321Skib } 2681205321Skib sd1->registered = 1; 2682205321Skib } 2683205321Skib return (0); 2684205321Skib} 2685205321Skib 2686205321Skibint 2687205321Skibsyscall32_helper_unregister(struct syscall_helper_data *sd) 2688205321Skib{ 2689205321Skib struct syscall_helper_data *sd1; 2690205321Skib 2691205321Skib for (sd1 = sd; sd1->registered != 0; sd1++) { 2692205321Skib syscall32_deregister(&sd1->syscall_no, &sd1->old_sysent); 2693205321Skib sd1->registered = 0; 2694205321Skib } 2695205321Skib return (0); 2696205321Skib} 2697205321Skib 2698205014Snwhitehornregister_t * 2699205014Snwhitehornfreebsd32_copyout_strings(struct image_params *imgp) 2700205014Snwhitehorn{ 2701211412Skib int argc, envc, i; 2702205014Snwhitehorn u_int32_t *vectp; 2703205014Snwhitehorn char *stringp, *destp; 2704205014Snwhitehorn u_int32_t *stack_base; 2705205014Snwhitehorn struct freebsd32_ps_strings *arginfo; 2706211412Skib char canary[sizeof(long) * 8]; 2707211412Skib int32_t pagesizes32[MAXPAGESIZES]; 2708205014Snwhitehorn size_t execpath_len; 2709205014Snwhitehorn int szsigcode; 2710205014Snwhitehorn 2711205014Snwhitehorn /* 2712205014Snwhitehorn * Calculate string base and vector table pointers. 2713205014Snwhitehorn * Also deal with signal trampoline code for this exec type. 2714205014Snwhitehorn */ 2715205014Snwhitehorn if (imgp->execpath != NULL && imgp->auxargs != NULL) 2716205014Snwhitehorn execpath_len = strlen(imgp->execpath) + 1; 2717205014Snwhitehorn else 2718205014Snwhitehorn execpath_len = 0; 2719211006Skib arginfo = (struct freebsd32_ps_strings *)curproc->p_sysent-> 2720211006Skib sv_psstrings; 2721217151Skib if (imgp->proc->p_sysent->sv_sigcode_base == 0) 2722217151Skib szsigcode = *(imgp->proc->p_sysent->sv_szsigcode); 2723217151Skib else 2724217151Skib szsigcode = 0; 2725205014Snwhitehorn destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE - 2726211412Skib roundup(execpath_len, sizeof(char *)) - 2727211412Skib roundup(sizeof(canary), sizeof(char *)) - 2728211412Skib roundup(sizeof(pagesizes32), sizeof(char *)) - 2729211412Skib roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *)); 2730205014Snwhitehorn 2731205014Snwhitehorn /* 2732205014Snwhitehorn * install sigcode 2733205014Snwhitehorn */ 2734217151Skib if (szsigcode != 0) 2735205014Snwhitehorn copyout(imgp->proc->p_sysent->sv_sigcode, 2736205014Snwhitehorn ((caddr_t)arginfo - szsigcode), szsigcode); 2737205014Snwhitehorn 2738205014Snwhitehorn /* 2739205014Snwhitehorn * Copy the image path for the rtld. 2740205014Snwhitehorn */ 2741205014Snwhitehorn if (execpath_len != 0) { 2742205014Snwhitehorn imgp->execpathp = (uintptr_t)arginfo - szsigcode - execpath_len; 2743205014Snwhitehorn copyout(imgp->execpath, (void *)imgp->execpathp, 2744205014Snwhitehorn execpath_len); 2745205014Snwhitehorn } 2746205014Snwhitehorn 2747205014Snwhitehorn /* 2748211412Skib * Prepare the canary for SSP. 2749211412Skib */ 2750211412Skib arc4rand(canary, sizeof(canary), 0); 2751211412Skib imgp->canary = (uintptr_t)arginfo - szsigcode - execpath_len - 2752211412Skib sizeof(canary); 2753211412Skib copyout(canary, (void *)imgp->canary, sizeof(canary)); 2754211412Skib imgp->canarylen = sizeof(canary); 2755211412Skib 2756211412Skib /* 2757211412Skib * Prepare the pagesizes array. 2758211412Skib */ 2759211412Skib for (i = 0; i < MAXPAGESIZES; i++) 2760211412Skib pagesizes32[i] = (uint32_t)pagesizes[i]; 2761211412Skib imgp->pagesizes = (uintptr_t)arginfo - szsigcode - execpath_len - 2762211412Skib roundup(sizeof(canary), sizeof(char *)) - sizeof(pagesizes32); 2763211412Skib copyout(pagesizes32, (void *)imgp->pagesizes, sizeof(pagesizes32)); 2764211412Skib imgp->pagesizeslen = sizeof(pagesizes32); 2765211412Skib 2766211412Skib /* 2767205014Snwhitehorn * If we have a valid auxargs ptr, prepare some room 2768205014Snwhitehorn * on the stack. 2769205014Snwhitehorn */ 2770205014Snwhitehorn if (imgp->auxargs) { 2771205014Snwhitehorn /* 2772205014Snwhitehorn * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for 2773205014Snwhitehorn * lower compatibility. 2774205014Snwhitehorn */ 2775205014Snwhitehorn imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size 2776205014Snwhitehorn : (AT_COUNT * 2); 2777205014Snwhitehorn /* 2778205014Snwhitehorn * The '+ 2' is for the null pointers at the end of each of 2779205014Snwhitehorn * the arg and env vector sets,and imgp->auxarg_size is room 2780205014Snwhitehorn * for argument of Runtime loader. 2781205014Snwhitehorn */ 2782205014Snwhitehorn vectp = (u_int32_t *) (destp - (imgp->args->argc + 2783205014Snwhitehorn imgp->args->envc + 2 + imgp->auxarg_size + execpath_len) * 2784205014Snwhitehorn sizeof(u_int32_t)); 2785205014Snwhitehorn } else 2786205014Snwhitehorn /* 2787205014Snwhitehorn * The '+ 2' is for the null pointers at the end of each of 2788205014Snwhitehorn * the arg and env vector sets 2789205014Snwhitehorn */ 2790205014Snwhitehorn vectp = (u_int32_t *) 2791205014Snwhitehorn (destp - (imgp->args->argc + imgp->args->envc + 2) * sizeof(u_int32_t)); 2792205014Snwhitehorn 2793205014Snwhitehorn /* 2794205014Snwhitehorn * vectp also becomes our initial stack base 2795205014Snwhitehorn */ 2796205014Snwhitehorn stack_base = vectp; 2797205014Snwhitehorn 2798205014Snwhitehorn stringp = imgp->args->begin_argv; 2799205014Snwhitehorn argc = imgp->args->argc; 2800205014Snwhitehorn envc = imgp->args->envc; 2801205014Snwhitehorn /* 2802205014Snwhitehorn * Copy out strings - arguments and environment. 2803205014Snwhitehorn */ 2804205014Snwhitehorn copyout(stringp, destp, ARG_MAX - imgp->args->stringspace); 2805205014Snwhitehorn 2806205014Snwhitehorn /* 2807205014Snwhitehorn * Fill in "ps_strings" struct for ps, w, etc. 2808205014Snwhitehorn */ 2809205014Snwhitehorn suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp); 2810205014Snwhitehorn suword32(&arginfo->ps_nargvstr, argc); 2811205014Snwhitehorn 2812205014Snwhitehorn /* 2813205014Snwhitehorn * Fill in argument portion of vector table. 2814205014Snwhitehorn */ 2815205014Snwhitehorn for (; argc > 0; --argc) { 2816205014Snwhitehorn suword32(vectp++, (u_int32_t)(intptr_t)destp); 2817205014Snwhitehorn while (*stringp++ != 0) 2818205014Snwhitehorn destp++; 2819205014Snwhitehorn destp++; 2820205014Snwhitehorn } 2821205014Snwhitehorn 2822205014Snwhitehorn /* a null vector table pointer separates the argp's from the envp's */ 2823205014Snwhitehorn suword32(vectp++, 0); 2824205014Snwhitehorn 2825205014Snwhitehorn suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp); 2826205014Snwhitehorn suword32(&arginfo->ps_nenvstr, envc); 2827205014Snwhitehorn 2828205014Snwhitehorn /* 2829205014Snwhitehorn * Fill in environment portion of vector table. 2830205014Snwhitehorn */ 2831205014Snwhitehorn for (; envc > 0; --envc) { 2832205014Snwhitehorn suword32(vectp++, (u_int32_t)(intptr_t)destp); 2833205014Snwhitehorn while (*stringp++ != 0) 2834205014Snwhitehorn destp++; 2835205014Snwhitehorn destp++; 2836205014Snwhitehorn } 2837205014Snwhitehorn 2838205014Snwhitehorn /* end of vector table is a null pointer */ 2839205014Snwhitehorn suword32(vectp, 0); 2840205014Snwhitehorn 2841205014Snwhitehorn return ((register_t *)stack_base); 2842205014Snwhitehorn} 2843205014Snwhitehorn 2844220158Skibint 2845220158Skibfreebsd32_kldstat(struct thread *td, struct freebsd32_kldstat_args *uap) 2846220158Skib{ 2847220158Skib struct kld_file_stat stat; 2848220158Skib struct kld32_file_stat stat32; 2849220158Skib int error, version; 2850220158Skib 2851220158Skib if ((error = copyin(&uap->stat->version, &version, sizeof(version))) 2852220158Skib != 0) 2853220158Skib return (error); 2854220158Skib if (version != sizeof(struct kld32_file_stat_1) && 2855220158Skib version != sizeof(struct kld32_file_stat)) 2856220158Skib return (EINVAL); 2857220158Skib 2858220158Skib error = kern_kldstat(td, uap->fileid, &stat); 2859220158Skib if (error != 0) 2860220158Skib return (error); 2861220158Skib 2862220158Skib bcopy(&stat.name[0], &stat32.name[0], sizeof(stat.name)); 2863220158Skib CP(stat, stat32, refs); 2864220158Skib CP(stat, stat32, id); 2865220158Skib PTROUT_CP(stat, stat32, address); 2866220158Skib CP(stat, stat32, size); 2867220158Skib bcopy(&stat.pathname[0], &stat32.pathname[0], sizeof(stat.pathname)); 2868220158Skib return (copyout(&stat32, uap->stat, version)); 2869220158Skib} 2870220791Smdf 2871220791Smdfint 2872220791Smdffreebsd32_posix_fallocate(struct thread *td, 2873220791Smdf struct freebsd32_posix_fallocate_args *uap) 2874220791Smdf{ 2875220791Smdf 2876229723Sjhb return (kern_posix_fallocate(td, uap->fd, 2877229723Sjhb PAIR32TO64(off_t, uap->offset), PAIR32TO64(off_t, uap->len))); 2878220791Smdf} 2879229723Sjhb 2880229723Sjhbint 2881229723Sjhbfreebsd32_posix_fadvise(struct thread *td, 2882229723Sjhb struct freebsd32_posix_fadvise_args *uap) 2883229723Sjhb{ 2884229723Sjhb 2885229723Sjhb return (kern_posix_fadvise(td, uap->fd, PAIR32TO64(off_t, uap->offset), 2886229723Sjhb PAIR32TO64(off_t, uap->len), uap->advice)); 2887229723Sjhb} 2888