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 <machine/../linux32/linux.h> instead of <machine/../linux/linux.h>
  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.
This commit is contained in:
tjr 2004-08-16 07:28:16 +00:00
parent e6930a385c
commit 6d0528abdf
12 changed files with 244 additions and 112 deletions

View File

@ -54,8 +54,15 @@ __FBSDID("$FreeBSD$");
#include <ufs/ufs/quota.h>
#include <ufs/ufs/ufsmount.h>
#include "opt_compat.h"
#if !COMPAT_LINUX32
#include <machine/../linux/linux.h>
#include <machine/../linux/linux_proto.h>
#else
#include <machine/../linux32/linux.h>
#include <machine/../linux32/linux32_proto.h>
#endif
#include <compat/linux/linux_util.h>
#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)

View File

@ -59,8 +59,15 @@ __FBSDID("$FreeBSD$");
#include <sys/dirent.h>
#include <ufs/ufs/dir.h> /* XXX only for DIRBLKSIZ */
#include "opt_compat.h"
#if !COMPAT_LINUX32
#include <machine/../linux/linux.h>
#include <machine/../linux/linux_proto.h>
#else
#include <machine/../linux32/linux.h>
#include <machine/../linux32/linux32_proto.h>
#endif
#include <compat/linux/linux_util.h>
static int

View File

@ -56,8 +56,15 @@ __FBSDID("$FreeBSD$");
#include <net/if_dl.h>
#include <net/if_types.h>
#include "opt_compat.h"
#if !COMPAT_LINUX32
#include <machine/../linux/linux.h>
#include <machine/../linux/linux_proto.h>
#else
#include <machine/../linux32/linux.h>
#include <machine/../linux32/linux32_proto.h>
#endif
#include <compat/linux/linux_ioctl.h>
#include <compat/linux/linux_mib.h>
@ -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;

View File

@ -39,9 +39,17 @@ __FBSDID("$FreeBSD$");
#include <sys/sem.h>
#include <sys/shm.h>
#include "opt_compat.h"
#if !COMPAT_LINUX32
#include <machine/../linux/linux.h>
#include <machine/../linux/linux_proto.h>
#include <machine/../linux/linux_ipc64.h>
#else
#include <machine/../linux32/linux.h>
#include <machine/../linux32/linux32_proto.h>
#include <machine/../linux32/linux32_ipc64.h>
#endif
#include <compat/linux/linux_ipc.h>
#include <compat/linux/linux_util.h>
@ -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);

View File

@ -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_ */

View File

@ -39,7 +39,13 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/mutex.h>
#include "opt_compat.h"
#if !COMPAT_LINUX32
#include <machine/../linux/linux.h>
#else
#include <machine/../linux32/linux.h>
#endif
#include <compat/linux/linux_mib.h>
struct linux_prison {

View File

@ -35,7 +35,9 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/blist.h>
#include <sys/fcntl.h>
#if defined(__i386__) || defined(__alpha__)
#include <sys/imgact_aout.h>
#endif
#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/limits.h>
@ -70,8 +72,15 @@ __FBSDID("$FreeBSD$");
#include <posix4/sched.h>
#include "opt_compat.h"
#if !COMPAT_LINUX32
#include <machine/../linux/linux.h>
#include <machine/../linux/linux_proto.h>
#else
#include <machine/../linux32/linux.h>
#include <machine/../linux32/linux32_proto.h>
#endif
#include <compat/linux/linux_mib.h>
#include <compat/linux/linux_util.h>
@ -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 @@ linux_uselib(struct thread *td, struct linux_uselib_args *args)
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)));
}

View File

@ -38,8 +38,15 @@ __FBSDID("$FreeBSD$");
#include <sys/syscallsubr.h>
#include <sys/sysproto.h>
#include "opt_compat.h"
#if !COMPAT_LINUX32
#include <machine/../linux/linux.h>
#include <machine/../linux/linux_proto.h>
#else
#include <machine/../linux32/linux.h>
#include <machine/../linux32/linux32_proto.h>
#endif
#include <compat/linux/linux_signal.h>
#include <compat/linux/linux_util.h>
@ -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);
}

View File

@ -60,8 +60,15 @@ __FBSDID("$FreeBSD$");
#include <netinet6/ip6_var.h>
#endif
#include "opt_compat.h"
#if !COMPAT_LINUX32
#include <machine/../linux/linux.h>
#include <machine/../linux/linux_proto.h>
#else
#include <machine/../linux32/linux.h>
#include <machine/../linux32/linux32_proto.h>
#endif
#include <compat/linux/linux_socket.h>
#include <compat/linux/linux_util.h>
@ -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:

View File

@ -45,8 +45,15 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/vnode.h>
#include "opt_compat.h"
#if !COMPAT_LINUX32
#include <machine/../linux/linux.h>
#include <machine/../linux/linux_proto.h>
#else
#include <machine/../linux32/linux.h>
#include <machine/../linux32/linux32_proto.h>
#endif
#include <compat/linux/linux_util.h>
@ -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__ */

View File

@ -38,8 +38,15 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/sbuf.h>
#include "opt_compat.h"
#if !COMPAT_LINUX32
#include <machine/../linux/linux.h>
#include <machine/../linux/linux_proto.h>
#else
#include <machine/../linux32/linux.h>
#include <machine/../linux32/linux32_proto.h>
#endif
#include <compat/linux/linux_util.h>
@ -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);

View File

@ -36,8 +36,15 @@ __FBSDID("$FreeBSD$");
#include <sys/sysproto.h>
#include <sys/systm.h>
#include "opt_compat.h"
#if !COMPAT_LINUX32
#include <machine/../linux/linux.h>
#include <machine/../linux/linux_proto.h>
#else
#include <machine/../linux32/linux.h>
#include <machine/../linux32/linux32_proto.h>
#endif
#include <compat/linux/linux_util.h>