On Tue, Feb 1, 2022 at 2:37 PM Richard Henderson < richard.henderson@linaro.org> wrote: > On 2/1/22 22:14, Warner Losh wrote: > > Implement do_bsd_{read,pread,readv,preadv}. Connect them to the system > > call table. > > > > Signed-off-by: Stacey Son > > Signed-off-by: Kyle Evans > > Signed-off-by: Warner Losh > > --- > > bsd-user/bsd-file.h | 79 +++++++++++++++++++++++++++++++++++ > > bsd-user/freebsd/os-syscall.c | 24 +++++++++++ > > 2 files changed, 103 insertions(+) > > > > diff --git a/bsd-user/bsd-file.h b/bsd-user/bsd-file.h > > index 2f743db38e1..5934cbd5612 100644 > > --- a/bsd-user/bsd-file.h > > +++ b/bsd-user/bsd-file.h > > @@ -36,4 +36,83 @@ extern struct iovec *lock_iovec(int type, abi_ulong > target_addr, int count, > > extern void unlock_iovec(struct iovec *vec, abi_ulong target_addr, int > count, > > int copy); > > > > +ssize_t safe_read(int fd, void *buf, size_t nbytes); > > +ssize_t safe_pread(int fd, void *buf, size_t nbytes, off_t offset); > > +ssize_t safe_readv(int fd, const struct iovec *iov, int iovcnt); > > +ssize_t safe_preadv(int fd, const struct iovec *iov, int iovcnt, off_t > offset); > > + > > +/* read(2) */ > > +static inline abi_long do_bsd_read(abi_long arg1, abi_long arg2, > abi_long arg3) > > +{ > > + abi_long ret; > > + void *p; > > + > > + p = lock_user(VERIFY_WRITE, arg2, arg3, 0); > > + if (p == NULL) { > > + return -TARGET_EFAULT; > > + } > > + ret = get_errno(safe_read(arg1, p, arg3)); > > + unlock_user(p, arg2, ret); > > + > > + return ret; > > +} > > + > > +/* pread(2) */ > > +static inline abi_long do_bsd_pread(void *cpu_env, abi_long arg1, > > + abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, > abi_long arg6) > > +{ > > + abi_long ret; > > + void *p; > > + > > + p = lock_user(VERIFY_WRITE, arg2, arg3, 0); > > + if (p == NULL) { > > + return -TARGET_EFAULT; > > + } > > + if (regpairs_aligned(cpu_env) != 0) { > > + arg4 = arg5; > > + arg5 = arg6; > > + } > > This would be clearer if you had started labeling from arg0. > There's a number of other changes this would force, so I'll defer it... Warner > But either way, > Reviewed-by: Richard Henderson > > > r~ > > > + ret = get_errno(safe_pread(arg1, p, arg3, target_arg64(arg4, > arg5))); > > + unlock_user(p, arg2, ret); > > + > > + return ret; > > +} > > + > > +/* readv(2) */ > > +static inline abi_long do_bsd_readv(abi_long arg1, abi_long arg2, > abi_long arg3) > > +{ > > + abi_long ret; > > + struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0); > > + > > + if (vec != NULL) { > > + ret = get_errno(safe_readv(arg1, vec, arg3)); > > + unlock_iovec(vec, arg2, arg3, 1); > > + } else { > > + ret = -host_to_target_errno(errno); > > + } > > + > > + return ret; > > +} > > + > > +/* preadv(2) */ > > +static inline abi_long do_bsd_preadv(void *cpu_env, abi_long arg1, > > + abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, > abi_long arg6) > > +{ > > + abi_long ret; > > + struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 1); > > + > > + if (vec != NULL) { > > + if (regpairs_aligned(cpu_env) != 0) { > > + arg4 = arg5; > > + arg5 = arg6; > > + } > > + ret = get_errno(safe_preadv(arg1, vec, arg3, target_arg64(arg4, > arg5))); > > + unlock_iovec(vec, arg2, arg3, 0); > > + } else { > > + ret = -host_to_target_errno(errno); > > + } > > + > > + return ret; > > +} > > + > > #endif /* !BSD_FILE_H_ */ > > diff --git a/bsd-user/freebsd/os-syscall.c > b/bsd-user/freebsd/os-syscall.c > > index fcfa6221182..dda79af53de 100644 > > --- a/bsd-user/freebsd/os-syscall.c > > +++ b/bsd-user/freebsd/os-syscall.c > > @@ -42,6 +42,14 @@ > > > > #include "bsd-file.h" > > > > +/* I/O */ > > +safe_syscall3(ssize_t, read, int, fd, void *, buf, size_t, nbytes); > > +safe_syscall4(ssize_t, pread, int, fd, void *, buf, size_t, nbytes, > off_t, > > + offset); > > +safe_syscall3(ssize_t, readv, int, fd, const struct iovec *, iov, int, > iovcnt); > > +safe_syscall4(ssize_t, preadv, int, fd, const struct iovec *, iov, int, > iovcnt, > > + off_t, offset); > > + > > void target_set_brk(abi_ulong new_brk) > > { > > } > > @@ -212,6 +220,22 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, > abi_long arg1, > > } > > > > switch (num) { > > + > > + /* > > + * File system calls. > > + */ > > + case TARGET_FREEBSD_NR_read: /* read(2) */ > > + ret = do_bsd_read(arg1, arg2, arg3); > > + break; > > + > > + case TARGET_FREEBSD_NR_pread: /* pread(2) */ > > + ret = do_bsd_pread(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6); > > + break; > > + > > + case TARGET_FREEBSD_NR_readv: /* readv(2) */ > > + ret = do_bsd_readv(arg1, arg2, arg3); > > + break; > > + > > default: > > gemu_log("qemu: unsupported syscall: %d\n", num); > > ret = -TARGET_ENOSYS; > >