From 6d0528abdfecb0a45eec1ee51b594803b1e11866 Mon Sep 17 00:00:00 2001 From: tjr Date: Mon, 16 Aug 2004 07:28:16 +0000 Subject: Changes to MI Linux emulation code necessary to run 32-bit Linux binaries on AMD64, and the general case where the emulated platform has different size pointers than we use natively: - declare certain structure members as l_uintptr_t and use the new PTRIN and PTROUT macros to convert to and from native pointers. - declare some structures __packed on amd64 when the layout would differ from that used on i386. - include instead of if compiling with COMPAT_LINUX32. This will need to be revisited before 32-bit and 64-bit Linux emulation support can coexist in the same kernel. - other small scattered changes. This should be a no-op on i386 and Alpha. --- sys/compat/linux/linux_file.c | 27 +++++++-- sys/compat/linux/linux_getcwd.c | 7 +++ sys/compat/linux/linux_ioctl.c | 15 ++++- sys/compat/linux/linux_ipc.c | 90 ++++++++++++++++++------------ sys/compat/linux/linux_ipc.h | 4 +- sys/compat/linux/linux_mib.c | 6 ++ sys/compat/linux/linux_misc.c | 35 ++++++++++-- sys/compat/linux/linux_signal.c | 17 +++++- sys/compat/linux/linux_socket.c | 118 +++++++++++++++++++++++----------------- sys/compat/linux/linux_stats.c | 11 +++- sys/compat/linux/linux_sysctl.c | 19 +++++-- sys/compat/linux/linux_uid16.c | 7 +++ 12 files changed, 244 insertions(+), 112 deletions(-) diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index 8200faf..8102b18 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -54,8 +54,15 @@ __FBSDID("$FreeBSD$"); #include #include +#include "opt_compat.h" + +#if !COMPAT_LINUX32 #include #include +#else +#include +#include +#endif #include #ifndef __alpha__ @@ -827,7 +834,11 @@ struct l_flock { l_off_t l_start; l_off_t l_len; l_pid_t l_pid; -}; +} +#if __amd64__ && COMPAT_LINUX32 +__packed +#endif +; static void linux_to_bsd_flock(struct l_flock *linux_flock, struct flock *bsd_flock) @@ -872,14 +883,18 @@ bsd_to_linux_flock(struct flock *bsd_flock, struct l_flock *linux_flock) linux_flock->l_pid = (l_pid_t)bsd_flock->l_pid; } -#if defined(__i386__) +#if defined(__i386__) || (defined(__amd64__) && COMPAT_LINUX32) struct l_flock64 { l_short l_type; l_short l_whence; l_loff_t l_start; l_loff_t l_len; l_pid_t l_pid; -}; +} +#if __amd64__ && COMPAT_LINUX32 +__packed +#endif +; static void linux_to_bsd_flock64(struct l_flock64 *linux_flock, struct flock *bsd_flock) @@ -923,7 +938,7 @@ bsd_to_linux_flock64(struct flock *bsd_flock, struct l_flock64 *linux_flock) linux_flock->l_len = (l_loff_t)bsd_flock->l_len; linux_flock->l_pid = (l_pid_t)bsd_flock->l_pid; } -#endif /* __i386__ */ +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ #if defined(__alpha__) #define linux_fcntl64_args linux_fcntl_args @@ -1051,7 +1066,7 @@ linux_fcntl(struct thread *td, struct linux_fcntl_args *args) return (fcntl_common(td, &args64)); } -#if defined(__i386__) +#if defined(__i386__) || (defined(__amd64__) && COMPAT_LINUX32) int linux_fcntl64(struct thread *td, struct linux_fcntl64_args *args) { @@ -1099,7 +1114,7 @@ linux_fcntl64(struct thread *td, struct linux_fcntl64_args *args) return (fcntl_common(td, args)); } -#endif /* __i386__ */ +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ int linux_chown(struct thread *td, struct linux_chown_args *args) diff --git a/sys/compat/linux/linux_getcwd.c b/sys/compat/linux/linux_getcwd.c index e3d9236..1bb137e 100644 --- a/sys/compat/linux/linux_getcwd.c +++ b/sys/compat/linux/linux_getcwd.c @@ -59,8 +59,15 @@ __FBSDID("$FreeBSD$"); #include #include /* XXX only for DIRBLKSIZ */ +#include "opt_compat.h" + +#if !COMPAT_LINUX32 #include #include +#else +#include +#include +#endif #include static int diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c index 0ee8e8e..677d8ff 100644 --- a/sys/compat/linux/linux_ioctl.c +++ b/sys/compat/linux/linux_ioctl.c @@ -56,8 +56,15 @@ __FBSDID("$FreeBSD$"); #include #include +#include "opt_compat.h" + +#if !COMPAT_LINUX32 #include #include +#else +#include +#include +#endif #include #include @@ -2081,7 +2088,11 @@ ifname_linux_to_bsd(const char *lxname, char *bsdname) static int linux_ifconf(struct thread *td, struct ifconf *uifc) { +#if COMPAT_LINUX32 + struct l_ifconf ifc; +#else struct ifconf ifc; +#endif struct l_ifreq ifr; struct ifnet *ifp; struct ifaddr *ifa; @@ -2094,7 +2105,7 @@ linux_ifconf(struct thread *td, struct ifconf *uifc) return (error); /* handle the 'request buffer size' case */ - if (ifc.ifc_buf == NULL) { + if (ifc.ifc_buf == PTROUT(NULL)) { ifc.ifc_len = 0; TAILQ_FOREACH(ifp, &ifnet, if_link) { TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { @@ -2108,7 +2119,7 @@ linux_ifconf(struct thread *td, struct ifconf *uifc) } /* much easier to use uiomove than keep track ourselves */ - iov.iov_base = ifc.ifc_buf; + iov.iov_base = PTRIN(ifc.ifc_buf); iov.iov_len = ifc.ifc_len; uio.uio_iov = &iov; uio.uio_iovcnt = 1; diff --git a/sys/compat/linux/linux_ipc.c b/sys/compat/linux/linux_ipc.c index 71b6d60..04dc772 100644 --- a/sys/compat/linux/linux_ipc.c +++ b/sys/compat/linux/linux_ipc.c @@ -39,9 +39,17 @@ __FBSDID("$FreeBSD$"); #include #include +#include "opt_compat.h" + +#if !COMPAT_LINUX32 #include #include #include +#else +#include +#include +#include +#endif #include #include @@ -133,8 +141,8 @@ bsd_to_linux_ipc_perm(struct ipc_perm *bpp, struct l_ipc_perm *lpp) struct l_msqid_ds { struct l_ipc_perm msg_perm; - struct l_msg *msg_first; /* first message on queue,unused */ - struct l_msg *msg_last; /* last message in queue,unused */ + l_uintptr_t msg_first; /* first message on queue,unused */ + l_uintptr_t msg_last; /* last message in queue,unused */ l_time_t msg_stime; /* last msgsnd time */ l_time_t msg_rtime; /* last msgrcv time */ l_time_t msg_ctime; /* last change time */ @@ -145,18 +153,26 @@ struct l_msqid_ds { l_ushort msg_qbytes; /* max number of bytes on queue */ l_pid_t msg_lspid; /* pid of last msgsnd */ l_pid_t msg_lrpid; /* last receive pid */ -}; +} +#if __amd64__ && COMPAT_LINUX32 +__packed +#endif +; struct l_semid_ds { struct l_ipc_perm sem_perm; l_time_t sem_otime; l_time_t sem_ctime; - void *sem_base; - void *sem_pending; - void *sem_pending_last; - void *undo; + l_uintptr_t sem_base; + l_uintptr_t sem_pending; + l_uintptr_t sem_pending_last; + l_uintptr_t undo; l_ushort sem_nsems; -}; +} +#if __amd64__ && COMPAT_LINUX32 +__packed +#endif +; struct l_shmid_ds { struct l_ipc_perm shm_perm; @@ -168,8 +184,8 @@ struct l_shmid_ds { l_ushort shm_lpid; l_short shm_nattch; l_ushort private1; - void *private2; - void *private3; + l_uintptr_t private2; + l_uintptr_t private3; }; static void @@ -179,7 +195,7 @@ linux_to_bsd_semid_ds(struct l_semid_ds *lsp, struct semid_ds *bsp) bsp->sem_otime = lsp->sem_otime; bsp->sem_ctime = lsp->sem_ctime; bsp->sem_nsems = lsp->sem_nsems; - bsp->sem_base = lsp->sem_base; + bsp->sem_base = PTRIN(lsp->sem_base); } static void @@ -189,7 +205,7 @@ bsd_to_linux_semid_ds(struct semid_ds *bsp, struct l_semid_ds *lsp) lsp->sem_otime = bsp->sem_otime; lsp->sem_ctime = bsp->sem_ctime; lsp->sem_nsems = bsp->sem_nsems; - lsp->sem_base = bsp->sem_base; + lsp->sem_base = PTROUT(bsp->sem_base); } static void @@ -203,7 +219,8 @@ linux_to_bsd_shmid_ds(struct l_shmid_ds *lsp, struct shmid_ds *bsp) bsp->shm_atime = lsp->shm_atime; bsp->shm_dtime = lsp->shm_dtime; bsp->shm_ctime = lsp->shm_ctime; - bsp->shm_internal = lsp->private3; /* this goes (yet) SOS */ + /* this goes (yet) SOS */ + bsp->shm_internal = PTRIN(lsp->private3); } static void @@ -217,7 +234,8 @@ bsd_to_linux_shmid_ds(struct shmid_ds *bsp, struct l_shmid_ds *lsp) lsp->shm_atime = bsp->shm_atime; lsp->shm_dtime = bsp->shm_dtime; lsp->shm_ctime = bsp->shm_ctime; - lsp->private3 = bsp->shm_internal; /* this goes (yet) SOS */ + /* this goes (yet) SOS */ + lsp->private3 = PTROUT(bsp->shm_internal); } static void @@ -447,7 +465,7 @@ linux_semop(struct thread *td, struct linux_semop_args *args) } */ bsd_args; bsd_args.semid = args->semid; - bsd_args.sops = (struct sembuf *)args->tsops; + bsd_args.sops = (struct sembuf *)PTRIN(args->tsops); bsd_args.nsops = args->nsops; return semop(td, &bsd_args); } @@ -516,7 +534,7 @@ linux_semctl(struct thread *td, struct linux_semctl_args *args) case LINUX_IPC_SET: bsd_args.cmd = IPC_SET; error = linux_semid_pullup(args->cmd & LINUX_IPC_64, - &linux_semid, (caddr_t)args->arg.buf); + &linux_semid, (caddr_t)PTRIN(args->arg.buf)); if (error) return (error); unptr->buf = stackgap_alloc(&sg, sizeof(struct semid_ds)); @@ -536,7 +554,7 @@ linux_semctl(struct thread *td, struct linux_semctl_args *args) unptr->buf->sem_perm); bsd_to_linux_semid_ds(unptr->buf, &linux_semid); return (linux_semid_pushdown(args->cmd & LINUX_IPC_64, - &linux_semid, (caddr_t)args->arg.buf)); + &linux_semid, (caddr_t)PTRIN(args->arg.buf))); case LINUX_IPC_INFO: case LINUX_SEM_INFO: bcopy(&seminfo, &linux_seminfo, sizeof(linux_seminfo) ); @@ -546,8 +564,8 @@ linux_semctl(struct thread *td, struct linux_semctl_args *args) linux_seminfo.semusz = used_semids; linux_seminfo.semaem = used_sems; */ - error = copyout(&linux_seminfo, args->arg.buf, - sizeof(linux_seminfo)); + error = copyout(&linux_seminfo, + PTRIN(args->arg.buf), sizeof(linux_seminfo)); if (error) return error; td->td_retval[0] = seminfo.semmni; @@ -575,7 +593,7 @@ linux_msgsnd(struct thread *td, struct linux_msgsnd_args *args) } */ bsd_args; bsd_args.msqid = args->msqid; - bsd_args.msgp = args->msgp; + bsd_args.msgp = PTRIN(args->msgp); bsd_args.msgsz = args->msgsz; bsd_args.msgflg = args->msgflg; return msgsnd(td, &bsd_args); @@ -593,7 +611,7 @@ linux_msgrcv(struct thread *td, struct linux_msgrcv_args *args) } */ bsd_args; bsd_args.msqid = args->msqid; - bsd_args.msgp = args->msgp; + bsd_args.msgp = PTRIN(args->msgp); bsd_args.msgsz = args->msgsz; bsd_args.msgtyp = args->msgtyp; bsd_args.msgflg = args->msgflg; @@ -626,7 +644,7 @@ linux_msgctl(struct thread *td, struct linux_msgctl_args *args) caddr_t sg = stackgap_init(); error = linux_msqid_pullup(args->cmd & LINUX_IPC_64, - &linux_msqid, (caddr_t)args->buf); + &linux_msqid, (caddr_t)PTRIN(args->buf)); if (error != 0) return (error); bsd_args.buf = (struct msqid_ds*)stackgap_alloc(&sg, @@ -644,7 +662,7 @@ linux_msgctl(struct thread *td, struct linux_msgctl_args *args) if (bsd_args.cmd == LINUX_IPC_STAT) { bsd_to_linux_msqid_ds(bsd_args.buf, &linux_msqid); return (linux_msqid_pushdown(args->cmd & LINUX_IPC_64, - &linux_msqid, (caddr_t)args->buf)); + &linux_msqid, (caddr_t)PTRIN(args->buf))); } return (0); @@ -659,14 +677,18 @@ linux_shmat(struct thread *td, struct linux_shmat_args *args) int shmflg; } */ bsd_args; int error; +#if defined(__i386__) || (defined(__amd64__) && COMPAT_LINUX32) + l_uintptr_t addr; +#endif bsd_args.shmid = args->shmid; - bsd_args.shmaddr = args->shmaddr; + bsd_args.shmaddr = PTRIN(args->shmaddr); bsd_args.shmflg = args->shmflg; if ((error = shmat(td, &bsd_args))) return error; -#ifdef __i386__ - if ((error = copyout(td->td_retval, args->raddr, sizeof(l_ulong)))) +#if defined(__i386__) || (defined(__amd64__) && COMPAT_LINUX32) + addr = td->td_retval[0]; + if ((error = copyout(&addr, PTRIN(args->raddr), sizeof(addr)))) return error; td->td_retval[0] = 0; #endif @@ -680,7 +702,7 @@ linux_shmdt(struct thread *td, struct linux_shmdt_args *args) void *shmaddr; } */ bsd_args; - bsd_args.shmaddr = args->shmaddr; + bsd_args.shmaddr = PTRIN(args->shmaddr); return shmdt(td, &bsd_args); } @@ -723,7 +745,7 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args) bsd_to_linux_shminfo(&bsd_shminfo, &linux_shminfo); return (linux_shminfo_pushdown(args->cmd & LINUX_IPC_64, - &linux_shminfo, (caddr_t)args->buf)); + &linux_shminfo, (caddr_t)PTRIN(args->buf))); } case LINUX_SHM_INFO: { @@ -737,7 +759,7 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args) bsd_to_linux_shm_info(&bsd_shm_info, &linux_shm_info); - return copyout(&linux_shm_info, (caddr_t)args->buf, + return copyout(&linux_shm_info, (caddr_t)PTRIN(args->buf), sizeof(struct l_shm_info)); } @@ -751,7 +773,7 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args) bsd_to_linux_shmid_ds(&bsd_shmid, &linux_shmid); return (linux_shmid_pushdown(args->cmd & LINUX_IPC_64, - &linux_shmid, (caddr_t)args->buf)); + &linux_shmid, (caddr_t)PTRIN(args->buf))); case LINUX_SHM_STAT: /* Perform shmctl wanting removed segments lookup */ @@ -763,11 +785,11 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args) bsd_to_linux_shmid_ds(&bsd_shmid, &linux_shmid); return (linux_shmid_pushdown(args->cmd & LINUX_IPC_64, - &linux_shmid, (caddr_t)args->buf)); + &linux_shmid, (caddr_t)PTRIN(args->buf))); case LINUX_IPC_SET: error = linux_shmid_pullup(args->cmd & LINUX_IPC_64, - &linux_shmid, (caddr_t)args->buf); + &linux_shmid, (caddr_t)PTRIN(args->buf)); if (error) return error; @@ -780,11 +802,11 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args) case LINUX_IPC_RMID: { void *buf; - if (args->buf == NULL) + if (args->buf == 0) buf = NULL; else { error = linux_shmid_pullup(args->cmd & LINUX_IPC_64, - &linux_shmid, (caddr_t)args->buf); + &linux_shmid, (caddr_t)PTRIN(args->buf)); if (error) return error; linux_to_bsd_shmid_ds(&linux_shmid, &bsd_shmid); diff --git a/sys/compat/linux/linux_ipc.h b/sys/compat/linux/linux_ipc.h index 33a85b7..2557f22 100644 --- a/sys/compat/linux/linux_ipc.h +++ b/sys/compat/linux/linux_ipc.h @@ -40,7 +40,7 @@ #define LINUX_IPC_64 0x0100 /* New version (support 32-bit UIDs, bigger message sizes, etc. */ -#ifdef __i386__ +#if defined(__i386__) || defined(__amd64__) struct linux_msgctl_args { @@ -135,6 +135,6 @@ int linux_shmctl(struct thread *, struct linux_shmctl_args *); int linux_shmdt(struct thread *, struct linux_shmdt_args *); int linux_shmget(struct thread *, struct linux_shmget_args *); -#endif /* __i386__ */ +#endif /* __i386__ || __amd64__ */ #endif /* _LINUX_IPC_H_ */ diff --git a/sys/compat/linux/linux_mib.c b/sys/compat/linux/linux_mib.c index ce1a708..8ebf68d 100644 --- a/sys/compat/linux/linux_mib.c +++ b/sys/compat/linux/linux_mib.c @@ -39,7 +39,13 @@ __FBSDID("$FreeBSD$"); #include #include +#include "opt_compat.h" + +#if !COMPAT_LINUX32 #include +#else +#include +#endif #include struct linux_prison { diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 1c8365e..c01b126 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -35,7 +35,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#if defined(__i386__) || defined(__alpha__) #include +#endif #include #include #include @@ -70,8 +72,15 @@ __FBSDID("$FreeBSD$"); #include +#include "opt_compat.h" + +#if !COMPAT_LINUX32 #include #include +#else +#include +#include +#endif #include #include @@ -237,6 +246,8 @@ linux_brk(struct thread *td, struct linux_brk_args *args) return 0; } +#if defined(__i386__) || defined(__alpha__) + int linux_uselib(struct thread *td, struct linux_uselib_args *args) { @@ -427,7 +438,7 @@ linux_uselib(struct thread *td, struct linux_uselib_args *args) goto cleanup; /* copy from kernel VM space to user space */ - error = copyout((void *)(uintptr_t)(buffer + file_offset), + error = copyout(PTRIN(buffer + file_offset), (void *)vmaddr, a_out->a_text + a_out->a_data); /* release temporary kernel space */ @@ -485,6 +496,8 @@ cleanup: return error; } +#endif /* __i386__ || __alpha__ */ + int linux_select(struct thread *td, struct linux_select_args *args) { @@ -610,7 +623,8 @@ linux_mremap(struct thread *td, struct linux_mremap_args *args) } if (args->new_len < args->old_len) { - bsd_args.addr = (caddr_t)(args->addr + args->new_len); + bsd_args.addr = + (caddr_t)((uintptr_t)args->addr + args->new_len); bsd_args.len = args->old_len - args->new_len; error = munmap(td, &bsd_args); } @@ -628,8 +642,8 @@ linux_msync(struct thread *td, struct linux_msync_args *args) { struct msync_args bsd_args; - bsd_args.addr = (caddr_t)args->addr; - bsd_args.len = args->len; + bsd_args.addr = (caddr_t)(uintptr_t)args->addr; + bsd_args.len = (uintptr_t)args->len; bsd_args.flags = args->fl & ~LINUX_MS_SYNC; return msync(td, &bsd_args); @@ -755,7 +769,7 @@ linux_newuname(struct thread *td, struct linux_newuname_args *args) return (copyout(&utsname, args->buf, sizeof(utsname))); } -#if defined(__i386__) +#if defined(__i386__) || (defined(__amd64__) && COMPAT_LINUX32) struct l_utimbuf { l_time_t l_actime; l_time_t l_modtime; @@ -793,7 +807,7 @@ linux_utime(struct thread *td, struct linux_utime_args *args) LFREEPATH(fname); return (error); } -#endif /* __i386__ */ +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ #define __WCLONE 0x80000000 @@ -1179,12 +1193,21 @@ linux_old_getrlimit(struct thread *td, struct linux_old_getrlimit_args *args) lim_rlimit(p, which, &bsd_rlim); PROC_UNLOCK(p); +#if !COMPAT_LINUX32 rlim.rlim_cur = (unsigned long)bsd_rlim.rlim_cur; if (rlim.rlim_cur == ULONG_MAX) rlim.rlim_cur = LONG_MAX; rlim.rlim_max = (unsigned long)bsd_rlim.rlim_max; if (rlim.rlim_max == ULONG_MAX) rlim.rlim_max = LONG_MAX; +#else + rlim.rlim_cur = (unsigned int)bsd_rlim.rlim_cur; + if (rlim.rlim_cur == UINT_MAX) + rlim.rlim_cur = INT_MAX; + rlim.rlim_max = (unsigned int)bsd_rlim.rlim_max; + if (rlim.rlim_max == UINT_MAX) + rlim.rlim_max = INT_MAX; +#endif return (copyout(&rlim, args->rlim, sizeof(rlim))); } diff --git a/sys/compat/linux/linux_signal.c b/sys/compat/linux/linux_signal.c index ba2b460..2bb7250 100644 --- a/sys/compat/linux/linux_signal.c +++ b/sys/compat/linux/linux_signal.c @@ -38,8 +38,15 @@ __FBSDID("$FreeBSD$"); #include #include +#include "opt_compat.h" + +#if !COMPAT_LINUX32 #include #include +#else +#include +#include +#endif #include #include @@ -90,7 +97,7 @@ linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa) { linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask); - bsa->sa_handler = lsa->lsa_handler; + bsa->sa_handler = PTRIN(lsa->lsa_handler); bsa->sa_flags = 0; if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP) bsa->sa_flags |= SA_NOCLDSTOP; @@ -113,8 +120,12 @@ bsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa) { bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask); +#if COMPAT_LINUX32 + lsa->lsa_handler = (uintptr_t)bsa->sa_handler; +#else lsa->lsa_handler = bsa->sa_handler; - lsa->lsa_restorer = NULL; /* unsupported */ +#endif + lsa->lsa_restorer = 0; /* unsupported */ lsa->lsa_flags = 0; if (bsa->sa_flags & SA_NOCLDSTOP) lsa->lsa_flags |= LINUX_SA_NOCLDSTOP; @@ -185,7 +196,7 @@ linux_signal(struct thread *td, struct linux_signal_args *args) LINUX_SIGEMPTYSET(nsa.lsa_mask); error = linux_do_sigaction(td, args->sig, &nsa, &osa); - td->td_retval[0] = (int)osa.lsa_handler; + td->td_retval[0] = (int)(intptr_t)osa.lsa_handler; return (error); } diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index 9fcbb63..fdba099 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -60,8 +60,15 @@ __FBSDID("$FreeBSD$"); #include #endif +#include "opt_compat.h" + +#if !COMPAT_LINUX32 #include #include +#else +#include +#include +#endif #include #include @@ -417,10 +424,10 @@ linux_check_hdrincl(struct thread *td, int s) struct linux_sendto_args { int s; - void *msg; + l_uintptr_t msg; int len; int flags; - caddr_t to; + l_uintptr_t to; int tolen; }; @@ -458,7 +465,8 @@ linux_sendto_hdrincl(struct thread *td, struct linux_sendto_args *linux_args) packet = (struct ip *)stackgap_alloc(&sg, linux_ip_copysize); /* Make a copy of the beginning of the packet to be sent */ - if ((error = copyin(linux_args->msg, packet, linux_ip_copysize))) + if ((error = copyin(PTRIN(linux_args->msg), packet, + linux_ip_copysize))) return (error); /* Convert fields from Linux to BSD raw IP socket format */ @@ -466,7 +474,7 @@ linux_sendto_hdrincl(struct thread *td, struct linux_sendto_args *linux_args) packet->ip_off = ntohs(packet->ip_off); /* Prepare the msghdr and iovec structures describing the new packet */ - msg.msg_name = linux_args->to; + msg.msg_name = PTRIN(linux_args->to); msg.msg_namelen = linux_args->tolen; msg.msg_iov = aiov; msg.msg_iovlen = 2; @@ -474,7 +482,8 @@ linux_sendto_hdrincl(struct thread *td, struct linux_sendto_args *linux_args) msg.msg_flags = 0; aiov[0].iov_base = (char *)packet; aiov[0].iov_len = linux_ip_copysize; - aiov[1].iov_base = (char *)(linux_args->msg) + linux_ip_copysize; + aiov[1].iov_base = (char *)PTRIN(linux_args->msg) + + linux_ip_copysize; aiov[1].iov_len = linux_args->len - linux_ip_copysize; error = linux_sendit(td, linux_args->s, &msg, linux_args->flags); return (error); @@ -549,7 +558,7 @@ linux_socket(struct thread *td, struct linux_socket_args *args) struct linux_bind_args { int s; - struct osockaddr *name; + l_uintptr_t name; int namelen; }; @@ -563,7 +572,8 @@ linux_bind(struct thread *td, struct linux_bind_args *args) if ((error = copyin(args, &linux_args, sizeof(linux_args)))) return (error); - error = linux_getsockaddr(&sa, linux_args.name, linux_args.namelen); + error = linux_getsockaddr(&sa, PTRIN(linux_args.name), + linux_args.namelen); if (error) return (error); @@ -572,7 +582,7 @@ linux_bind(struct thread *td, struct linux_bind_args *args) struct linux_connect_args { int s; - struct osockaddr * name; + l_uintptr_t name; int namelen; }; int linux_connect(struct thread *, struct linux_connect_args *); @@ -594,7 +604,8 @@ linux_connect(struct thread *td, struct linux_connect_args *args) return (error); #endif /* __alpha__ */ - error = linux_getsockaddr(&sa, (struct osockaddr *)linux_args.name, + error = linux_getsockaddr(&sa, + (struct osockaddr *)PTRIN(linux_args.name), linux_args.namelen); if (error) return (error); @@ -647,8 +658,8 @@ linux_listen(struct thread *td, struct linux_listen_args *args) struct linux_accept_args { int s; - struct osockaddr *addr; - int *namelen; + l_uintptr_t addr; + l_uintptr_t namelen; }; static int @@ -675,13 +686,13 @@ linux_accept(struct thread *td, struct linux_accept_args *args) bsd_args.s = linux_args.s; /* XXX: */ - bsd_args.name = (struct sockaddr * __restrict)linux_args.addr; - bsd_args.anamelen = linux_args.namelen; /* XXX */ + bsd_args.name = (struct sockaddr * __restrict)PTRIN(linux_args.addr); + bsd_args.anamelen = PTRIN(linux_args.namelen);/* XXX */ error = oaccept(td, &bsd_args); if (error) return (error); if (linux_args.addr) { - error = linux_sa_put(linux_args.addr); + error = linux_sa_put(PTRIN(linux_args.addr)); if (error) { c_args.fd = td->td_retval[0]; (void)close(td, &c_args); @@ -704,8 +715,8 @@ linux_accept(struct thread *td, struct linux_accept_args *args) struct linux_getsockname_args { int s; - struct osockaddr *addr; - int *namelen; + l_uintptr_t addr; + l_uintptr_t namelen; }; static int @@ -724,12 +735,12 @@ linux_getsockname(struct thread *td, struct linux_getsockname_args *args) bsd_args.fdes = linux_args.s; /* XXX: */ - bsd_args.asa = (struct sockaddr * __restrict)linux_args.addr; - bsd_args.alen = linux_args.namelen; /* XXX */ + bsd_args.asa = (struct sockaddr * __restrict)PTRIN(linux_args.addr); + bsd_args.alen = PTRIN(linux_args.namelen); /* XXX */ error = ogetsockname(td, &bsd_args); if (error) return (error); - error = linux_sa_put(linux_args.addr); + error = linux_sa_put(PTRIN(linux_args.addr)); if (error) return (error); return (0); @@ -737,8 +748,8 @@ linux_getsockname(struct thread *td, struct linux_getsockname_args *args) struct linux_getpeername_args { int s; - struct osockaddr *addr; - int *namelen; + l_uintptr_t addr; + l_uintptr_t namelen; }; static int @@ -756,12 +767,12 @@ linux_getpeername(struct thread *td, struct linux_getpeername_args *args) return (error); bsd_args.fdes = linux_args.s; - bsd_args.asa = (caddr_t) linux_args.addr; - bsd_args.alen = linux_args.namelen; + bsd_args.asa = (caddr_t)PTRIN(linux_args.addr); + bsd_args.alen = (int *)PTRIN(linux_args.namelen); error = ogetpeername(td, &bsd_args); if (error) return (error); - error = linux_sa_put(linux_args.addr); + error = linux_sa_put(PTRIN(linux_args.addr)); if (error) return (error); return (0); @@ -771,7 +782,7 @@ struct linux_socketpair_args { int domain; int type; int protocol; - int *rsv; + l_uintptr_t rsv; }; static int @@ -795,13 +806,13 @@ linux_socketpair(struct thread *td, struct linux_socketpair_args *args) bsd_args.type = linux_args.type; bsd_args.protocol = linux_args.protocol; - bsd_args.rsv = linux_args.rsv; + bsd_args.rsv = (int *)PTRIN(linux_args.rsv); return (socketpair(td, &bsd_args)); } struct linux_send_args { int s; - void *msg; + l_uintptr_t msg; int len; int flags; }; @@ -824,7 +835,7 @@ linux_send(struct thread *td, struct linux_send_args *args) return (error); bsd_args.s = linux_args.s; - bsd_args.buf = linux_args.msg; + bsd_args.buf = (caddr_t)PTRIN(linux_args.msg); bsd_args.len = linux_args.len; bsd_args.flags = linux_args.flags; bsd_args.to = NULL; @@ -834,7 +845,7 @@ linux_send(struct thread *td, struct linux_send_args *args) struct linux_recv_args { int s; - void *msg; + l_uintptr_t msg; int len; int flags; }; @@ -857,7 +868,7 @@ linux_recv(struct thread *td, struct linux_recv_args *args) return (error); bsd_args.s = linux_args.s; - bsd_args.buf = linux_args.msg; + bsd_args.buf = (caddr_t)PTRIN(linux_args.msg); bsd_args.len = linux_args.len; bsd_args.flags = linux_args.flags; bsd_args.from = NULL; @@ -880,13 +891,13 @@ linux_sendto(struct thread *td, struct linux_sendto_args *args) /* IP_HDRINCL set, tweak the packet before sending */ return (linux_sendto_hdrincl(td, &linux_args)); - msg.msg_name = linux_args.to; + msg.msg_name = PTRIN(linux_args.to); msg.msg_namelen = linux_args.tolen; msg.msg_iov = &aiov; msg.msg_iovlen = 1; msg.msg_control = NULL; msg.msg_flags = 0; - aiov.iov_base = linux_args.msg; + aiov.iov_base = PTRIN(linux_args.msg); aiov.iov_len = linux_args.len; error = linux_sendit(td, linux_args.s, &msg, linux_args.flags); return (error); @@ -894,11 +905,11 @@ linux_sendto(struct thread *td, struct linux_sendto_args *args) struct linux_recvfrom_args { int s; - void *buf; + l_uintptr_t buf; int len; int flags; - caddr_t from; - int *fromlen; + l_uintptr_t from; + l_uintptr_t fromlen; }; static int @@ -919,17 +930,18 @@ linux_recvfrom(struct thread *td, struct linux_recvfrom_args *args) return (error); bsd_args.s = linux_args.s; - bsd_args.buf = linux_args.buf; + bsd_args.buf = PTRIN(linux_args.buf); bsd_args.len = linux_args.len; bsd_args.flags = linux_to_bsd_msg_flags(linux_args.flags); /* XXX: */ - bsd_args.from = (struct sockaddr * __restrict)linux_args.from; - bsd_args.fromlenaddr = linux_args.fromlen; /* XXX */ + bsd_args.from = (struct sockaddr * __restrict)PTRIN(linux_args.from); + bsd_args.fromlenaddr = PTRIN(linux_args.fromlen);/* XXX */ error = orecvfrom(td, &bsd_args); if (error) return (error); if (linux_args.from) { - error = linux_sa_put((struct osockaddr *) linux_args.from); + error = linux_sa_put((struct osockaddr *) + PTRIN(linux_args.from)); if (error) return (error); } @@ -938,7 +950,7 @@ linux_recvfrom(struct thread *td, struct linux_recvfrom_args *args) struct linux_sendmsg_args { int s; - const struct msghdr *msg; + l_uintptr_t msg; int flags; }; @@ -950,10 +962,12 @@ linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args) struct iovec *iov; int error; + /* XXXTJR sendmsg is broken on amd64 */ + error = copyin(args, &linux_args, sizeof(linux_args)); if (error) return (error); - error = copyin(linux_args.msg, &msg, sizeof(msg)); + error = copyin(PTRIN(linux_args.msg), &msg, sizeof(msg)); if (error) return (error); error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); @@ -968,7 +982,7 @@ linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args) struct linux_recvmsg_args { int s; - struct msghdr *msg; + l_uintptr_t msg; int flags; }; @@ -985,11 +999,13 @@ linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args) struct cmsghdr *cmsg; int error; + /* XXXTJR recvmsg is broken on amd64 */ + if ((error = copyin(args, &linux_args, sizeof(linux_args)))) return (error); bsd_args.s = linux_args.s; - bsd_args.msg = linux_args.msg; + bsd_args.msg = PTRIN(linux_args.msg); bsd_args.flags = linux_to_bsd_msg_flags(linux_args.flags); error = recvmsg(td, &bsd_args); if (error) @@ -1000,7 +1016,7 @@ linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args) cmsg->cmsg_level = bsd_to_linux_sockopt_level(cmsg->cmsg_level); } - error = copyin(linux_args.msg, &msg, sizeof(msg)); + error = copyin(PTRIN(linux_args.msg), &msg, sizeof(msg)); if (error) return (error); if (msg.msg_name && msg.msg_namelen > 2) @@ -1035,7 +1051,7 @@ struct linux_setsockopt_args { int s; int level; int optname; - void *optval; + l_uintptr_t optval; int optlen; }; @@ -1076,7 +1092,7 @@ linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args) return (EINVAL); bsd_args.name = name; - bsd_args.val = linux_args.optval; + bsd_args.val = PTRIN(linux_args.optval); bsd_args.valsize = linux_args.optlen; return (setsockopt(td, &bsd_args)); } @@ -1085,8 +1101,8 @@ struct linux_getsockopt_args { int s; int level; int optname; - void *optval; - int *optlen; + l_uintptr_t optval; + l_uintptr_t optlen; }; static int @@ -1126,15 +1142,15 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args) return (EINVAL); bsd_args.name = name; - bsd_args.val = linux_args.optval; - bsd_args.avalsize = linux_args.optlen; + bsd_args.val = PTRIN(linux_args.optval); + bsd_args.avalsize = PTRIN(linux_args.optlen); return (getsockopt(td, &bsd_args)); } int linux_socketcall(struct thread *td, struct linux_socketcall_args *args) { - void *arg = (void *)args->args; + void *arg = (void *)(intptr_t)args->args; switch (args->what) { case LINUX_SOCKET: diff --git a/sys/compat/linux/linux_stats.c b/sys/compat/linux/linux_stats.c index 4a78554..406b524 100644 --- a/sys/compat/linux/linux_stats.c +++ b/sys/compat/linux/linux_stats.c @@ -45,8 +45,15 @@ __FBSDID("$FreeBSD$"); #include #include +#include "opt_compat.h" + +#if !COMPAT_LINUX32 #include #include +#else +#include +#include +#endif #include @@ -392,7 +399,7 @@ linux_ustat(struct thread *td, struct linux_ustat_args *args) return (copyout(&lu, args->ubuf, sizeof(lu))); } -#if defined(__i386__) +#if defined(__i386__) || (defined(__amd64__) && COMPAT_LINUX32) static int stat64_copyout(struct stat *buf, void *ubuf) @@ -531,4 +538,4 @@ linux_fstat64(struct thread *td, struct linux_fstat64_args *args) return (error); } -#endif /* __i386__ */ +#endif /* __i386__ || __amd64__ */ diff --git a/sys/compat/linux/linux_sysctl.c b/sys/compat/linux/linux_sysctl.c index aecdf73..72bc1c4 100644 --- a/sys/compat/linux/linux_sysctl.c +++ b/sys/compat/linux/linux_sysctl.c @@ -38,8 +38,15 @@ __FBSDID("$FreeBSD$"); #include #include +#include "opt_compat.h" + +#if !COMPAT_LINUX32 #include #include +#else +#include +#include +#endif #include @@ -63,16 +70,16 @@ handle_string(struct l___sysctl_args *la, char *value) { int error; - if (la->oldval != NULL) { + if (la->oldval != 0) { l_int len = strlen(value); - error = copyout(value, la->oldval, len + 1); - if (!error && la->oldlenp != NULL) - error = copyout(&len, la->oldlenp, sizeof(len)); + error = copyout(value, PTRIN(la->oldval), len + 1); + if (!error && la->oldlenp != 0) + error = copyout(&len, PTRIN(la->oldlenp), sizeof(len)); if (error) return (error); } - if (la->newval != NULL) + if (la->newval != 0) return (ENOTDIR); return (0); @@ -94,7 +101,7 @@ linux_sysctl(struct thread *td, struct linux_sysctl_args *args) return (ENOTDIR); mib = malloc(la.nlen * sizeof(l_int), M_TEMP, M_WAITOK); - error = copyin(la.name, mib, la.nlen * sizeof(l_int)); + error = copyin(PTRIN(la.name), mib, la.nlen * sizeof(l_int)); if (error) { free(mib, M_TEMP); return (error); diff --git a/sys/compat/linux/linux_uid16.c b/sys/compat/linux/linux_uid16.c index 5afcf2d..83543ee 100644 --- a/sys/compat/linux/linux_uid16.c +++ b/sys/compat/linux/linux_uid16.c @@ -36,8 +36,15 @@ __FBSDID("$FreeBSD$"); #include #include +#include "opt_compat.h" + +#if !COMPAT_LINUX32 #include #include +#else +#include +#include +#endif #include -- cgit v1.1