diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2008-11-29 14:55:24 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2008-11-29 14:55:24 +0000 |
commit | 41f53a3665baa9001141a4209d125281995466c0 (patch) | |
tree | d0e9219e58adcb026ccfa6ff28841b0418f85d70 /sys/amd64/linux32 | |
parent | 759e7c0bbbde06260ea843460c8ebb91c6a0ca92 (diff) | |
download | src-41f53a3665baa9001141a4209d125281995466c0.tar.gz src-41f53a3665baa9001141a4209d125281995466c0.zip |
Fix iovec32 for linux32/amd64.
Add a custom version of copyiniov() to deal with the 32-bit iovec
pointers from userland (to be used later).
Adjust prototypes for linux_readv() and linux_writev() to use new
l_iovec32 definition and to match actual linux code. In particular,
use ulong for fd (why ?).
Submitted by: dchagin
Notes
Notes:
svn path=/head/; revision=185438
Diffstat (limited to 'sys/amd64/linux32')
-rw-r--r-- | sys/amd64/linux32/linux.h | 10 | ||||
-rw-r--r-- | sys/amd64/linux32/linux32_machdep.c | 43 | ||||
-rw-r--r-- | sys/amd64/linux32/syscalls.master | 8 |
3 files changed, 47 insertions, 14 deletions
diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h index 60598a0019b9..020ddd24d1f5 100644 --- a/sys/amd64/linux32/linux.h +++ b/sys/amd64/linux32/linux.h @@ -885,6 +885,16 @@ struct l_user_desc { (LINUX_CLONE_VM | LINUX_CLONE_FS | LINUX_CLONE_FILES | \ LINUX_CLONE_SIGHAND | LINUX_CLONE_THREAD) +struct iovec; + +struct l_iovec32 { + uint32_t iov_base; + l_size_t iov_len; +}; + +int linux32_copyiniov(struct l_iovec32 *iovp32, l_ulong iovcnt, + struct iovec **iovp, int error); + /* robust futexes */ struct linux_robust_list { l_uintptr_t next; diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c index fcf01c89eb19..c8869e2e79e5 100644 --- a/sys/amd64/linux32/linux32_machdep.c +++ b/sys/amd64/linux32/linux32_machdep.c @@ -232,20 +232,15 @@ linux_execve(struct thread *td, struct linux_execve_args *args) return (error); } -struct iovec32 { - u_int32_t iov_base; - int iov_len; -}; - -CTASSERT(sizeof(struct iovec32) == 8); +CTASSERT(sizeof(struct l_iovec32) == 8); static int -linux32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop) +linux32_copyinuio(struct l_iovec32 *iovp, l_ulong iovcnt, struct uio **uiop) { - struct iovec32 iov32; + struct l_iovec32 iov32; struct iovec *iov; struct uio *uio; - u_int iovlen; + uint32_t iovlen; int error, i; *uiop = NULL; @@ -255,7 +250,7 @@ linux32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop) uio = malloc(iovlen + sizeof(*uio), M_IOV, M_WAITOK); iov = (struct iovec *)(uio + 1); for (i = 0; i < iovcnt; i++) { - error = copyin(&iovp[i], &iov32, sizeof(struct iovec32)); + error = copyin(&iovp[i], &iov32, sizeof(struct l_iovec32)); if (error) { free(uio, M_IOV); return (error); @@ -281,6 +276,34 @@ linux32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop) } int +linux32_copyiniov(struct l_iovec32 *iovp32, l_ulong iovcnt, struct iovec **iovp, + int error) +{ + struct l_iovec32 iov32; + struct iovec *iov; + uint32_t iovlen; + int i; + + *iovp = NULL; + if (iovcnt > UIO_MAXIOV) + return (error); + iovlen = iovcnt * sizeof(struct iovec); + iov = malloc(iovlen, M_IOV, M_WAITOK); + for (i = 0; i < iovcnt; i++) { + error = copyin(&iovp32[i], &iov32, sizeof(struct l_iovec32)); + if (error) { + free(iov, M_IOV); + return (error); + } + iov[i].iov_base = PTRIN(iov32.iov_base); + iov[i].iov_len = iov32.iov_len; + } + *iovp = iov; + return(0); + +} + +int linux_readv(struct thread *td, struct linux_readv_args *uap) { struct uio *auio; diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master index fe0485ea8b40..9aff0fc93171 100644 --- a/sys/amd64/linux32/syscalls.master +++ b/sys/amd64/linux32/syscalls.master @@ -252,10 +252,10 @@ 143 AUE_FLOCK NOPROTO { int flock(int fd, int how); } 144 AUE_MSYNC STD { int linux_msync(l_ulong addr, \ l_size_t len, l_int fl); } -145 AUE_READV STD { int linux_readv(int fd, struct iovec32 *iovp, \ - u_int iovcnt); } -146 AUE_WRITEV STD { int linux_writev(int fd, struct iovec32 *iovp, \ - u_int iovcnt); } +145 AUE_READV STD { int linux_readv(l_ulong fd, struct l_iovec32 *iovp, \ + l_ulong iovcnt); } +146 AUE_WRITEV STD { int linux_writev(l_ulong fd, struct l_iovec32 *iovp, \ + l_ulong iovcnt); } 147 AUE_GETSID STD { int linux_getsid(l_pid_t pid); } 148 AUE_NULL STD { int linux_fdatasync(l_uint fd); } 149 AUE_SYSCTL STD { int linux_sysctl( \ |