diff options
Diffstat (limited to 'sys/compat/freebsd32/freebsd32_misc.c')
-rw-r--r-- | sys/compat/freebsd32/freebsd32_misc.c | 864 |
1 files changed, 216 insertions, 648 deletions
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 75b290b365f0..f0fde2b3c147 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -31,6 +31,8 @@ __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" +#define __ELF_WORD_SIZE 32 + #include <sys/param.h> #include <sys/bus.h> #include <sys/clock.h> @@ -44,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include <sys/lock.h> #include <sys/malloc.h> #include <sys/file.h> /* Must come after sys/malloc.h */ +#include <sys/imgact.h> #include <sys/mbuf.h> #include <sys/mman.h> #include <sys/module.h> @@ -91,6 +94,7 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_extern.h> #include <machine/cpu.h> +#include <machine/elf.h> #include <security/audit/audit.h> @@ -115,6 +119,38 @@ CTASSERT(sizeof(struct sigaction32) == 24); static int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count); static int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count); +#if BYTE_ORDER == BIG_ENDIAN +#define PAIR32TO64(type, name) ((name ## 2) | ((type)(name ## 1) << 32)) +#define RETVAL_HI 0 +#define RETVAL_LO 1 +#else +#define PAIR32TO64(type, name) ((name ## 1) | ((type)(name ## 2) << 32)) +#define RETVAL_HI 1 +#define RETVAL_LO 0 +#endif + +void +freebsd32_rusage_out(const struct rusage *s, struct rusage32 *s32) +{ + + TV_CP(*s, *s32, ru_utime); + TV_CP(*s, *s32, ru_stime); + CP(*s, *s32, ru_maxrss); + CP(*s, *s32, ru_ixrss); + CP(*s, *s32, ru_idrss); + CP(*s, *s32, ru_isrss); + CP(*s, *s32, ru_minflt); + CP(*s, *s32, ru_majflt); + CP(*s, *s32, ru_nswap); + CP(*s, *s32, ru_inblock); + CP(*s, *s32, ru_oublock); + CP(*s, *s32, ru_msgsnd); + CP(*s, *s32, ru_msgrcv); + CP(*s, *s32, ru_nsignals); + CP(*s, *s32, ru_nvcsw); + CP(*s, *s32, ru_nivcsw); +} + int freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) { @@ -132,22 +168,7 @@ freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) if (uap->status != NULL) error = copyout(&status, uap->status, sizeof(status)); if (uap->rusage != NULL && error == 0) { - TV_CP(ru, ru32, ru_utime); - TV_CP(ru, ru32, ru_stime); - CP(ru, ru32, ru_maxrss); - CP(ru, ru32, ru_ixrss); - CP(ru, ru32, ru_idrss); - CP(ru, ru32, ru_isrss); - CP(ru, ru32, ru_minflt); - CP(ru, ru32, ru_majflt); - CP(ru, ru32, ru_nswap); - CP(ru, ru32, ru_inblock); - CP(ru, ru32, ru_oublock); - CP(ru, ru32, ru_msgsnd); - CP(ru, ru32, ru_msgrcv); - CP(ru, ru32, ru_nsignals); - CP(ru, ru32, ru_nvcsw); - CP(ru, ru32, ru_nivcsw); + freebsd32_rusage_out(&ru, &ru32); error = copyout(&ru32, uap->rusage, sizeof(ru32)); } return (error); @@ -426,8 +447,7 @@ freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) int prot = uap->prot; int flags = uap->flags; int fd = uap->fd; - off_t pos = (uap->poslo - | ((off_t)uap->poshi << 32)); + off_t pos = PAIR32TO64(off_t,uap->pos); #ifdef __ia64__ vm_size_t pageoff; int error; @@ -523,8 +543,8 @@ freebsd6_freebsd32_mmap(struct thread *td, struct freebsd6_freebsd32_mmap_args * ap.prot = uap->prot; ap.flags = uap->flags; ap.fd = uap->fd; - ap.poslo = uap->poslo; - ap.poshi = uap->poshi; + ap.pos1 = uap->pos1; + ap.pos2 = uap->pos2; return (freebsd32_mmap(td, &ap)); } @@ -586,7 +606,6 @@ freebsd32_select(struct thread *td, struct freebsd32_select_args *uap) } else tvp = NULL; /* - * XXX big-endian needs to convert the fd_sets too. * XXX Do pointers need PTRIN()? */ return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp, @@ -620,7 +639,6 @@ freebsd32_pselect(struct thread *td, struct freebsd32_pselect_args *uap) } else uset = NULL; /* - * XXX big-endian needs to convert the fd_sets too. * XXX Do pointers need PTRIN()? */ error = kern_pselect(td, uap->nd, uap->in, uap->ou, uap->ex, tvp, @@ -744,22 +762,7 @@ freebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) if (error) return (error); if (uap->rusage != NULL) { - TV_CP(s, s32, ru_utime); - TV_CP(s, s32, ru_stime); - CP(s, s32, ru_maxrss); - CP(s, s32, ru_ixrss); - CP(s, s32, ru_idrss); - CP(s, s32, ru_isrss); - CP(s, s32, ru_minflt); - CP(s, s32, ru_majflt); - CP(s, s32, ru_nswap); - CP(s, s32, ru_inblock); - CP(s, s32, ru_oublock); - CP(s, s32, ru_msgsnd); - CP(s, s32, ru_msgrcv); - CP(s, s32, ru_nsignals); - CP(s, s32, ru_nvcsw); - CP(s, s32, ru_nivcsw); + freebsd32_rusage_out(&s, &s32); error = copyout(&s32, uap->rusage, sizeof(s32)); } return (error); @@ -843,7 +846,7 @@ freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap) error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); if (error) return (error); - error = kern_preadv(td, uap->fd, auio, uap->offset); + error = kern_preadv(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset)); free(auio, M_IOV); return (error); } @@ -857,12 +860,12 @@ freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap) error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); if (error) return (error); - error = kern_pwritev(td, uap->fd, auio, uap->offset); + error = kern_pwritev(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset)); free(auio, M_IOV); return (error); } -static int +int freebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp, int error) { @@ -1389,591 +1392,6 @@ freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatf } #endif -#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ - defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) -static void -freebsd32_ipcperm_old_in(struct ipc_perm32_old *ip32, struct ipc_perm *ip) -{ - - CP(*ip32, *ip, cuid); - CP(*ip32, *ip, cgid); - CP(*ip32, *ip, uid); - CP(*ip32, *ip, gid); - CP(*ip32, *ip, mode); - CP(*ip32, *ip, seq); - CP(*ip32, *ip, key); -} - -static void -freebsd32_ipcperm_old_out(struct ipc_perm *ip, struct ipc_perm32_old *ip32) -{ - - CP(*ip, *ip32, cuid); - CP(*ip, *ip32, cgid); - CP(*ip, *ip32, uid); - CP(*ip, *ip32, gid); - CP(*ip, *ip32, mode); - CP(*ip, *ip32, seq); - CP(*ip, *ip32, key); -} -#endif - -static void -freebsd32_ipcperm_in(struct ipc_perm32 *ip32, struct ipc_perm *ip) -{ - - CP(*ip32, *ip, cuid); - CP(*ip32, *ip, cgid); - CP(*ip32, *ip, uid); - CP(*ip32, *ip, gid); - CP(*ip32, *ip, mode); - CP(*ip32, *ip, seq); - CP(*ip32, *ip, key); -} - -static void -freebsd32_ipcperm_out(struct ipc_perm *ip, struct ipc_perm32 *ip32) -{ - - CP(*ip, *ip32, cuid); - CP(*ip, *ip32, cgid); - CP(*ip, *ip32, uid); - CP(*ip, *ip32, gid); - CP(*ip, *ip32, mode); - CP(*ip, *ip32, seq); - CP(*ip, *ip32, key); -} - -int -freebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) -{ - -#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ - defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) - switch (uap->which) { - case 0: - return (freebsd7_freebsd32_semctl(td, - (struct freebsd7_freebsd32_semctl_args *)&uap->a2)); - default: - return (semsys(td, (struct semsys_args *)uap)); - } -#else - return (nosys(td, NULL)); -#endif -} - -#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ - defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) -int -freebsd7_freebsd32_semctl(struct thread *td, - struct freebsd7_freebsd32_semctl_args *uap) -{ - struct semid_ds32_old dsbuf32; - struct semid_ds dsbuf; - union semun semun; - union semun32 arg; - register_t rval; - int error; - - switch (uap->cmd) { - case SEM_STAT: - case IPC_SET: - case IPC_STAT: - case GETALL: - case SETVAL: - case SETALL: - error = copyin(uap->arg, &arg, sizeof(arg)); - if (error) - return (error); - break; - } - - switch (uap->cmd) { - case SEM_STAT: - case IPC_STAT: - semun.buf = &dsbuf; - break; - case IPC_SET: - error = copyin(PTRIN(arg.buf), &dsbuf32, sizeof(dsbuf32)); - if (error) - return (error); - freebsd32_ipcperm_old_in(&dsbuf32.sem_perm, &dsbuf.sem_perm); - PTRIN_CP(dsbuf32, dsbuf, sem_base); - CP(dsbuf32, dsbuf, sem_nsems); - CP(dsbuf32, dsbuf, sem_otime); - CP(dsbuf32, dsbuf, sem_ctime); - semun.buf = &dsbuf; - break; - case GETALL: - case SETALL: - semun.array = PTRIN(arg.array); - break; - case SETVAL: - semun.val = arg.val; - break; - } - - error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun, - &rval); - if (error) - return (error); - - switch (uap->cmd) { - case SEM_STAT: - case IPC_STAT: - bzero(&dsbuf32, sizeof(dsbuf32)); - freebsd32_ipcperm_old_out(&dsbuf.sem_perm, &dsbuf32.sem_perm); - PTROUT_CP(dsbuf, dsbuf32, sem_base); - CP(dsbuf, dsbuf32, sem_nsems); - CP(dsbuf, dsbuf32, sem_otime); - CP(dsbuf, dsbuf32, sem_ctime); - error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32)); - break; - } - - if (error == 0) - td->td_retval[0] = rval; - return (error); -} -#endif - -int -freebsd32_semctl(struct thread *td, struct freebsd32_semctl_args *uap) -{ - struct semid_ds32 dsbuf32; - struct semid_ds dsbuf; - union semun semun; - union semun32 arg; - register_t rval; - int error; - - switch (uap->cmd) { - case SEM_STAT: - case IPC_SET: - case IPC_STAT: - case GETALL: - case SETVAL: - case SETALL: - error = copyin(uap->arg, &arg, sizeof(arg)); - if (error) - return (error); - break; - } - - switch (uap->cmd) { - case SEM_STAT: - case IPC_STAT: - semun.buf = &dsbuf; - break; - case IPC_SET: - error = copyin(PTRIN(arg.buf), &dsbuf32, sizeof(dsbuf32)); - if (error) - return (error); - freebsd32_ipcperm_in(&dsbuf32.sem_perm, &dsbuf.sem_perm); - PTRIN_CP(dsbuf32, dsbuf, sem_base); - CP(dsbuf32, dsbuf, sem_nsems); - CP(dsbuf32, dsbuf, sem_otime); - CP(dsbuf32, dsbuf, sem_ctime); - semun.buf = &dsbuf; - break; - case GETALL: - case SETALL: - semun.array = PTRIN(arg.array); - break; - case SETVAL: - semun.val = arg.val; - break; - } - - error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun, - &rval); - if (error) - return (error); - - switch (uap->cmd) { - case SEM_STAT: - case IPC_STAT: - bzero(&dsbuf32, sizeof(dsbuf32)); - freebsd32_ipcperm_out(&dsbuf.sem_perm, &dsbuf32.sem_perm); - PTROUT_CP(dsbuf, dsbuf32, sem_base); - CP(dsbuf, dsbuf32, sem_nsems); - CP(dsbuf, dsbuf32, sem_otime); - CP(dsbuf, dsbuf32, sem_ctime); - error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32)); - break; - } - - if (error == 0) - td->td_retval[0] = rval; - return (error); -} - -int -freebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap) -{ - -#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ - defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) - switch (uap->which) { - case 0: - return (freebsd7_freebsd32_msgctl(td, - (struct freebsd7_freebsd32_msgctl_args *)&uap->a2)); - case 2: - return (freebsd32_msgsnd(td, - (struct freebsd32_msgsnd_args *)&uap->a2)); - case 3: - return (freebsd32_msgrcv(td, - (struct freebsd32_msgrcv_args *)&uap->a2)); - default: - return (msgsys(td, (struct msgsys_args *)uap)); - } -#else - return (nosys(td, NULL)); -#endif -} - -#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ - defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) -int -freebsd7_freebsd32_msgctl(struct thread *td, - struct freebsd7_freebsd32_msgctl_args *uap) -{ - struct msqid_ds msqbuf; - struct msqid_ds32_old msqbuf32; - int error; - - if (uap->cmd == IPC_SET) { - error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32)); - if (error) - return (error); - freebsd32_ipcperm_old_in(&msqbuf32.msg_perm, &msqbuf.msg_perm); - PTRIN_CP(msqbuf32, msqbuf, msg_first); - PTRIN_CP(msqbuf32, msqbuf, msg_last); - CP(msqbuf32, msqbuf, msg_cbytes); - CP(msqbuf32, msqbuf, msg_qnum); - CP(msqbuf32, msqbuf, msg_qbytes); - CP(msqbuf32, msqbuf, msg_lspid); - CP(msqbuf32, msqbuf, msg_lrpid); - CP(msqbuf32, msqbuf, msg_stime); - CP(msqbuf32, msqbuf, msg_rtime); - CP(msqbuf32, msqbuf, msg_ctime); - } - error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf); - if (error) - return (error); - if (uap->cmd == IPC_STAT) { - bzero(&msqbuf32, sizeof(msqbuf32)); - freebsd32_ipcperm_old_out(&msqbuf.msg_perm, &msqbuf32.msg_perm); - PTROUT_CP(msqbuf, msqbuf32, msg_first); - PTROUT_CP(msqbuf, msqbuf32, msg_last); - CP(msqbuf, msqbuf32, msg_cbytes); - CP(msqbuf, msqbuf32, msg_qnum); - CP(msqbuf, msqbuf32, msg_qbytes); - CP(msqbuf, msqbuf32, msg_lspid); - CP(msqbuf, msqbuf32, msg_lrpid); - CP(msqbuf, msqbuf32, msg_stime); - CP(msqbuf, msqbuf32, msg_rtime); - CP(msqbuf, msqbuf32, msg_ctime); - error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32)); - } - return (error); -} -#endif - -int -freebsd32_msgctl(struct thread *td, struct freebsd32_msgctl_args *uap) -{ - struct msqid_ds msqbuf; - struct msqid_ds32 msqbuf32; - int error; - - if (uap->cmd == IPC_SET) { - error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32)); - if (error) - return (error); - freebsd32_ipcperm_in(&msqbuf32.msg_perm, &msqbuf.msg_perm); - PTRIN_CP(msqbuf32, msqbuf, msg_first); - PTRIN_CP(msqbuf32, msqbuf, msg_last); - CP(msqbuf32, msqbuf, msg_cbytes); - CP(msqbuf32, msqbuf, msg_qnum); - CP(msqbuf32, msqbuf, msg_qbytes); - CP(msqbuf32, msqbuf, msg_lspid); - CP(msqbuf32, msqbuf, msg_lrpid); - CP(msqbuf32, msqbuf, msg_stime); - CP(msqbuf32, msqbuf, msg_rtime); - CP(msqbuf32, msqbuf, msg_ctime); - } - error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf); - if (error) - return (error); - if (uap->cmd == IPC_STAT) { - freebsd32_ipcperm_out(&msqbuf.msg_perm, &msqbuf32.msg_perm); - PTROUT_CP(msqbuf, msqbuf32, msg_first); - PTROUT_CP(msqbuf, msqbuf32, msg_last); - CP(msqbuf, msqbuf32, msg_cbytes); - CP(msqbuf, msqbuf32, msg_qnum); - CP(msqbuf, msqbuf32, msg_qbytes); - CP(msqbuf, msqbuf32, msg_lspid); - CP(msqbuf, msqbuf32, msg_lrpid); - CP(msqbuf, msqbuf32, msg_stime); - CP(msqbuf, msqbuf32, msg_rtime); - CP(msqbuf, msqbuf32, msg_ctime); - error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32)); - } - return (error); -} - -int -freebsd32_msgsnd(struct thread *td, struct freebsd32_msgsnd_args *uap) -{ - const void *msgp; - long mtype; - int32_t mtype32; - int error; - - msgp = PTRIN(uap->msgp); - if ((error = copyin(msgp, &mtype32, sizeof(mtype32))) != 0) - return (error); - mtype = mtype32; - return (kern_msgsnd(td, uap->msqid, - (const char *)msgp + sizeof(mtype32), - uap->msgsz, uap->msgflg, mtype)); -} - -int -freebsd32_msgrcv(struct thread *td, struct freebsd32_msgrcv_args *uap) -{ - void *msgp; - long mtype; - int32_t mtype32; - int error; - - msgp = PTRIN(uap->msgp); - if ((error = kern_msgrcv(td, uap->msqid, - (char *)msgp + sizeof(mtype32), uap->msgsz, - uap->msgtyp, uap->msgflg, &mtype)) != 0) - return (error); - mtype32 = (int32_t)mtype; - return (copyout(&mtype32, msgp, sizeof(mtype32))); -} - -int -freebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap) -{ - -#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ - defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) - switch (uap->which) { - case 0: { /* shmat */ - struct shmat_args ap; - - ap.shmid = uap->a2; - ap.shmaddr = PTRIN(uap->a3); - ap.shmflg = uap->a4; - return (sysent[SYS_shmat].sy_call(td, &ap)); - } - case 2: { /* shmdt */ - struct shmdt_args ap; - - ap.shmaddr = PTRIN(uap->a2); - return (sysent[SYS_shmdt].sy_call(td, &ap)); - } - case 3: { /* shmget */ - struct shmget_args ap; - - ap.key = uap->a2; - ap.size = uap->a3; - ap.shmflg = uap->a4; - return (sysent[SYS_shmget].sy_call(td, &ap)); - } - case 4: { /* shmctl */ - struct freebsd7_freebsd32_shmctl_args ap; - - ap.shmid = uap->a2; - ap.cmd = uap->a3; - ap.buf = PTRIN(uap->a4); - return (freebsd7_freebsd32_shmctl(td, &ap)); - } - case 1: /* oshmctl */ - default: - return (EINVAL); - } -#else - return (nosys(td, NULL)); -#endif -} - -#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ - defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) -int -freebsd7_freebsd32_shmctl(struct thread *td, - struct freebsd7_freebsd32_shmctl_args *uap) -{ - int error = 0; - union { - struct shmid_ds shmid_ds; - struct shm_info shm_info; - struct shminfo shminfo; - } u; - union { - struct shmid_ds32_old shmid_ds32; - struct shm_info32 shm_info32; - struct shminfo32 shminfo32; - } u32; - size_t sz; - - if (uap->cmd == IPC_SET) { - if ((error = copyin(uap->buf, &u32.shmid_ds32, - sizeof(u32.shmid_ds32)))) - goto done; - freebsd32_ipcperm_old_in(&u32.shmid_ds32.shm_perm, - &u.shmid_ds.shm_perm); - CP(u32.shmid_ds32, u.shmid_ds, shm_segsz); - CP(u32.shmid_ds32, u.shmid_ds, shm_lpid); - CP(u32.shmid_ds32, u.shmid_ds, shm_cpid); - CP(u32.shmid_ds32, u.shmid_ds, shm_nattch); - CP(u32.shmid_ds32, u.shmid_ds, shm_atime); - CP(u32.shmid_ds32, u.shmid_ds, shm_dtime); - CP(u32.shmid_ds32, u.shmid_ds, shm_ctime); - } - - error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz); - if (error) - goto done; - - /* Cases in which we need to copyout */ - switch (uap->cmd) { - case IPC_INFO: - CP(u.shminfo, u32.shminfo32, shmmax); - CP(u.shminfo, u32.shminfo32, shmmin); - CP(u.shminfo, u32.shminfo32, shmmni); - CP(u.shminfo, u32.shminfo32, shmseg); - CP(u.shminfo, u32.shminfo32, shmall); - error = copyout(&u32.shminfo32, uap->buf, - sizeof(u32.shminfo32)); - break; - case SHM_INFO: - CP(u.shm_info, u32.shm_info32, used_ids); - CP(u.shm_info, u32.shm_info32, shm_rss); - CP(u.shm_info, u32.shm_info32, shm_tot); - CP(u.shm_info, u32.shm_info32, shm_swp); - CP(u.shm_info, u32.shm_info32, swap_attempts); - CP(u.shm_info, u32.shm_info32, swap_successes); - error = copyout(&u32.shm_info32, uap->buf, - sizeof(u32.shm_info32)); - break; - case SHM_STAT: - case IPC_STAT: - freebsd32_ipcperm_old_out(&u.shmid_ds.shm_perm, - &u32.shmid_ds32.shm_perm); - if (u.shmid_ds.shm_segsz > INT32_MAX) - u32.shmid_ds32.shm_segsz = INT32_MAX; - else - CP(u.shmid_ds, u32.shmid_ds32, shm_segsz); - CP(u.shmid_ds, u32.shmid_ds32, shm_lpid); - CP(u.shmid_ds, u32.shmid_ds32, shm_cpid); - CP(u.shmid_ds, u32.shmid_ds32, shm_nattch); - CP(u.shmid_ds, u32.shmid_ds32, shm_atime); - CP(u.shmid_ds, u32.shmid_ds32, shm_dtime); - CP(u.shmid_ds, u32.shmid_ds32, shm_ctime); - u32.shmid_ds32.shm_internal = 0; - error = copyout(&u32.shmid_ds32, uap->buf, - sizeof(u32.shmid_ds32)); - break; - } - -done: - if (error) { - /* Invalidate the return value */ - td->td_retval[0] = -1; - } - return (error); -} -#endif - -int -freebsd32_shmctl(struct thread *td, struct freebsd32_shmctl_args *uap) -{ - int error = 0; - union { - struct shmid_ds shmid_ds; - struct shm_info shm_info; - struct shminfo shminfo; - } u; - union { - struct shmid_ds32 shmid_ds32; - struct shm_info32 shm_info32; - struct shminfo32 shminfo32; - } u32; - size_t sz; - - if (uap->cmd == IPC_SET) { - if ((error = copyin(uap->buf, &u32.shmid_ds32, - sizeof(u32.shmid_ds32)))) - goto done; - freebsd32_ipcperm_in(&u32.shmid_ds32.shm_perm, - &u.shmid_ds.shm_perm); - CP(u32.shmid_ds32, u.shmid_ds, shm_segsz); - CP(u32.shmid_ds32, u.shmid_ds, shm_lpid); - CP(u32.shmid_ds32, u.shmid_ds, shm_cpid); - CP(u32.shmid_ds32, u.shmid_ds, shm_nattch); - CP(u32.shmid_ds32, u.shmid_ds, shm_atime); - CP(u32.shmid_ds32, u.shmid_ds, shm_dtime); - CP(u32.shmid_ds32, u.shmid_ds, shm_ctime); - } - - error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz); - if (error) - goto done; - - /* Cases in which we need to copyout */ - switch (uap->cmd) { - case IPC_INFO: - CP(u.shminfo, u32.shminfo32, shmmax); - CP(u.shminfo, u32.shminfo32, shmmin); - CP(u.shminfo, u32.shminfo32, shmmni); - CP(u.shminfo, u32.shminfo32, shmseg); - CP(u.shminfo, u32.shminfo32, shmall); - error = copyout(&u32.shminfo32, uap->buf, - sizeof(u32.shminfo32)); - break; - case SHM_INFO: - CP(u.shm_info, u32.shm_info32, used_ids); - CP(u.shm_info, u32.shm_info32, shm_rss); - CP(u.shm_info, u32.shm_info32, shm_tot); - CP(u.shm_info, u32.shm_info32, shm_swp); - CP(u.shm_info, u32.shm_info32, swap_attempts); - CP(u.shm_info, u32.shm_info32, swap_successes); - error = copyout(&u32.shm_info32, uap->buf, - sizeof(u32.shm_info32)); - break; - case SHM_STAT: - case IPC_STAT: - freebsd32_ipcperm_out(&u.shmid_ds.shm_perm, - &u32.shmid_ds32.shm_perm); - if (u.shmid_ds.shm_segsz > INT32_MAX) - u32.shmid_ds32.shm_segsz = INT32_MAX; - else - CP(u.shmid_ds, u32.shmid_ds32, shm_segsz); - CP(u.shmid_ds, u32.shmid_ds32, shm_lpid); - CP(u.shmid_ds, u32.shmid_ds32, shm_cpid); - CP(u.shmid_ds, u32.shmid_ds32, shm_nattch); - CP(u.shmid_ds, u32.shmid_ds32, shm_atime); - CP(u.shmid_ds, u32.shmid_ds32, shm_dtime); - CP(u.shmid_ds, u32.shmid_ds32, shm_ctime); - error = copyout(&u32.shmid_ds32, uap->buf, - sizeof(u32.shmid_ds32)); - break; - } - -done: - if (error) { - /* Invalidate the return value */ - td->td_retval[0] = -1; - } - return (error); -} - int freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) { @@ -1982,7 +1400,7 @@ freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) ap.fd = uap->fd; ap.buf = uap->buf; ap.nbyte = uap->nbyte; - ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); + ap.offset = PAIR32TO64(off_t,uap->offset); return (pread(td, &ap)); } @@ -1994,7 +1412,7 @@ freebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) ap.fd = uap->fd; ap.buf = uap->buf; ap.nbyte = uap->nbyte; - ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); + ap.offset = PAIR32TO64(off_t,uap->offset); return (pwrite(td, &ap)); } @@ -2006,13 +1424,13 @@ freebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) off_t pos; ap.fd = uap->fd; - ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); + ap.offset = PAIR32TO64(off_t,uap->offset); ap.whence = uap->whence; error = lseek(td, &ap); /* Expand the quad return into two parts for eax and edx */ pos = *(off_t *)(td->td_retval); - td->td_retval[0] = pos & 0xffffffff; /* %eax */ - td->td_retval[1] = pos >> 32; /* %edx */ + td->td_retval[RETVAL_LO] = pos & 0xffffffff; /* %eax */ + td->td_retval[RETVAL_HI] = pos >> 32; /* %edx */ return error; } @@ -2022,7 +1440,7 @@ freebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) struct truncate_args ap; ap.path = uap->path; - ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); + ap.length = PAIR32TO64(off_t,uap->length); return (truncate(td, &ap)); } @@ -2032,7 +1450,7 @@ freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) struct ftruncate_args ap; ap.fd = uap->fd; - ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); + ap.length = PAIR32TO64(off_t,uap->length); return (ftruncate(td, &ap)); } @@ -2064,7 +1482,7 @@ freebsd6_freebsd32_pread(struct thread *td, struct freebsd6_freebsd32_pread_args ap.fd = uap->fd; ap.buf = uap->buf; ap.nbyte = uap->nbyte; - ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); + ap.offset = PAIR32TO64(off_t,uap->offset); return (pread(td, &ap)); } @@ -2076,7 +1494,7 @@ freebsd6_freebsd32_pwrite(struct thread *td, struct freebsd6_freebsd32_pwrite_ar ap.fd = uap->fd; ap.buf = uap->buf; ap.nbyte = uap->nbyte; - ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); + ap.offset = PAIR32TO64(off_t,uap->offset); return (pwrite(td, &ap)); } @@ -2088,13 +1506,13 @@ freebsd6_freebsd32_lseek(struct thread *td, struct freebsd6_freebsd32_lseek_args off_t pos; ap.fd = uap->fd; - ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); + ap.offset = PAIR32TO64(off_t,uap->offset); ap.whence = uap->whence; error = lseek(td, &ap); /* Expand the quad return into two parts for eax and edx */ pos = *(off_t *)(td->td_retval); - td->td_retval[0] = pos & 0xffffffff; /* %eax */ - td->td_retval[1] = pos >> 32; /* %edx */ + td->td_retval[RETVAL_LO] = pos & 0xffffffff; /* %eax */ + td->td_retval[RETVAL_HI] = pos >> 32; /* %edx */ return error; } @@ -2104,7 +1522,7 @@ freebsd6_freebsd32_truncate(struct thread *td, struct freebsd6_freebsd32_truncat struct truncate_args ap; ap.path = uap->path; - ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); + ap.length = PAIR32TO64(off_t,uap->length); return (truncate(td, &ap)); } @@ -2114,7 +1532,7 @@ freebsd6_freebsd32_ftruncate(struct thread *td, struct freebsd6_freebsd32_ftrunc struct ftruncate_args ap; ap.fd = uap->fd; - ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); + ap.length = PAIR32TO64(off_t,uap->length); return (ftruncate(td, &ap)); } #endif /* COMPAT_FREEBSD6 */ @@ -2141,7 +1559,7 @@ freebsd32_do_sendfile(struct thread *td, ap.fd = uap->fd; ap.s = uap->s; - ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); + ap.offset = PAIR32TO64(off_t,uap->offset); ap.nbytes = uap->nbytes; ap.hdtr = (struct sf_hdtr *)uap->hdtr; /* XXX not used */ ap.sbytes = uap->sbytes; @@ -2208,9 +1626,9 @@ copy_stat( struct stat *in, struct stat32 *out) CP(*in, *out, st_uid); CP(*in, *out, st_gid); CP(*in, *out, st_rdev); - TS_CP(*in, *out, st_atimespec); - TS_CP(*in, *out, st_mtimespec); - TS_CP(*in, *out, st_ctimespec); + TS_CP(*in, *out, st_atim); + TS_CP(*in, *out, st_mtim); + TS_CP(*in, *out, st_ctim); CP(*in, *out, st_size); CP(*in, *out, st_blocks); CP(*in, *out, st_blksize); @@ -2879,7 +2297,7 @@ freebsd32_cpuset_setid(struct thread *td, struct cpuset_setid_args ap; ap.which = uap->which; - ap.id = (uap->idlo | ((id_t)uap->idhi << 32)); + ap.id = PAIR32TO64(id_t,uap->id); ap.setid = uap->setid; return (cpuset_setid(td, &ap)); @@ -2893,7 +2311,7 @@ freebsd32_cpuset_getid(struct thread *td, ap.level = uap->level; ap.which = uap->which; - ap.id = (uap->idlo | ((id_t)uap->idhi << 32)); + ap.id = PAIR32TO64(id_t,uap->id); ap.setid = uap->setid; return (cpuset_getid(td, &ap)); @@ -2907,7 +2325,7 @@ freebsd32_cpuset_getaffinity(struct thread *td, ap.level = uap->level; ap.which = uap->which; - ap.id = (uap->idlo | ((id_t)uap->idhi << 32)); + ap.id = PAIR32TO64(id_t,uap->id); ap.cpusetsize = uap->cpusetsize; ap.mask = uap->mask; @@ -2922,7 +2340,7 @@ freebsd32_cpuset_setaffinity(struct thread *td, ap.level = uap->level; ap.which = uap->which; - ap.id = (uap->idlo | ((id_t)uap->idhi << 32)); + ap.id = PAIR32TO64(id_t,uap->id); ap.cpusetsize = uap->cpusetsize; ap.mask = uap->mask; @@ -3072,3 +2490,153 @@ syscall32_module_handler(struct module *mod, int what, void *arg) return (error); } } + +int +syscall32_helper_register(struct syscall_helper_data *sd) +{ + struct syscall_helper_data *sd1; + int error; + + for (sd1 = sd; sd1->syscall_no != NO_SYSCALL; sd1++) { + error = syscall32_register(&sd1->syscall_no, &sd1->new_sysent, + &sd1->old_sysent); + if (error != 0) { + syscall32_helper_unregister(sd); + return (error); + } + sd1->registered = 1; + } + return (0); +} + +int +syscall32_helper_unregister(struct syscall_helper_data *sd) +{ + struct syscall_helper_data *sd1; + + for (sd1 = sd; sd1->registered != 0; sd1++) { + syscall32_deregister(&sd1->syscall_no, &sd1->old_sysent); + sd1->registered = 0; + } + return (0); +} + +register_t * +freebsd32_copyout_strings(struct image_params *imgp) +{ + int argc, envc; + u_int32_t *vectp; + char *stringp, *destp; + u_int32_t *stack_base; + struct freebsd32_ps_strings *arginfo; + size_t execpath_len; + int szsigcode; + + /* + * Calculate string base and vector table pointers. + * Also deal with signal trampoline code for this exec type. + */ + if (imgp->execpath != NULL && imgp->auxargs != NULL) + execpath_len = strlen(imgp->execpath) + 1; + else + execpath_len = 0; + arginfo = (struct freebsd32_ps_strings *)FREEBSD32_PS_STRINGS; + szsigcode = *(imgp->proc->p_sysent->sv_szsigcode); + destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE - + roundup(execpath_len, sizeof(char *)) - + roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *)); + + /* + * install sigcode + */ + if (szsigcode) + copyout(imgp->proc->p_sysent->sv_sigcode, + ((caddr_t)arginfo - szsigcode), szsigcode); + + /* + * Copy the image path for the rtld. + */ + if (execpath_len != 0) { + imgp->execpathp = (uintptr_t)arginfo - szsigcode - execpath_len; + copyout(imgp->execpath, (void *)imgp->execpathp, + execpath_len); + } + + /* + * If we have a valid auxargs ptr, prepare some room + * on the stack. + */ + if (imgp->auxargs) { + /* + * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for + * lower compatibility. + */ + imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size + : (AT_COUNT * 2); + /* + * The '+ 2' is for the null pointers at the end of each of + * the arg and env vector sets,and imgp->auxarg_size is room + * for argument of Runtime loader. + */ + vectp = (u_int32_t *) (destp - (imgp->args->argc + + imgp->args->envc + 2 + imgp->auxarg_size + execpath_len) * + sizeof(u_int32_t)); + } else + /* + * The '+ 2' is for the null pointers at the end of each of + * the arg and env vector sets + */ + vectp = (u_int32_t *) + (destp - (imgp->args->argc + imgp->args->envc + 2) * sizeof(u_int32_t)); + + /* + * vectp also becomes our initial stack base + */ + stack_base = vectp; + + stringp = imgp->args->begin_argv; + argc = imgp->args->argc; + envc = imgp->args->envc; + /* + * Copy out strings - arguments and environment. + */ + copyout(stringp, destp, ARG_MAX - imgp->args->stringspace); + + /* + * Fill in "ps_strings" struct for ps, w, etc. + */ + suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp); + suword32(&arginfo->ps_nargvstr, argc); + + /* + * Fill in argument portion of vector table. + */ + for (; argc > 0; --argc) { + suword32(vectp++, (u_int32_t)(intptr_t)destp); + while (*stringp++ != 0) + destp++; + destp++; + } + + /* a null vector table pointer separates the argp's from the envp's */ + suword32(vectp++, 0); + + suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp); + suword32(&arginfo->ps_nenvstr, envc); + + /* + * Fill in environment portion of vector table. + */ + for (; envc > 0; --envc) { + suword32(vectp++, (u_int32_t)(intptr_t)destp); + while (*stringp++ != 0) + destp++; + destp++; + } + + /* end of vector table is a null pointer */ + suword32(vectp, 0); + + return ((register_t *)stack_base); +} + |