summaryrefslogtreecommitdiffstats
path: root/sys/amd64/linux32
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2008-11-29 14:55:24 +0000
committerkib <kib@FreeBSD.org>2008-11-29 14:55:24 +0000
commitbfe2c8cb22c42d50fb6fe83d2e151ff32f7af3b5 (patch)
treed0e9219e58adcb026ccfa6ff28841b0418f85d70 /sys/amd64/linux32
parent7a6d0a128f2abd041034ac5092a012538437e540 (diff)
downloadFreeBSD-src-bfe2c8cb22c42d50fb6fe83d2e151ff32f7af3b5.zip
FreeBSD-src-bfe2c8cb22c42d50fb6fe83d2e151ff32f7af3b5.tar.gz
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
Diffstat (limited to 'sys/amd64/linux32')
-rw-r--r--sys/amd64/linux32/linux.h10
-rw-r--r--sys/amd64/linux32/linux32_machdep.c43
-rw-r--r--sys/amd64/linux32/syscalls.master8
3 files changed, 47 insertions, 14 deletions
diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h
index 60598a0..020ddd2 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 fcf01c8..c8869e2 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 fe0485e..9aff0fc 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( \
OpenPOWER on IntegriCloud