Message ID | 1446059583-16340-4-git-send-email-laurent@vivier.eu |
---|---|
State | New |
Headers | show |
On 28 October 2015 at 19:13, Laurent Vivier <laurent@vivier.eu> wrote: > Signed-off-by: Laurent Vivier <laurent@vivier.eu> > --- > linux-user/syscall.c | 41 ++++++++++++++++++++++++++++++++++++----- > 1 file changed, 36 insertions(+), 5 deletions(-) > > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index 41b85b4..31b5c2c 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -296,9 +296,11 @@ static bitmask_transtbl fcntl_flags_tbl[] = { > }; > > typedef abi_long (*TargetFdDataFunc)(void *, size_t); > +typedef abi_long (*TargetFdAddrFunc)(void *, abi_ulong, socklen_t); > typedef struct TargetFdTrans { > TargetFdDataFunc host_to_target_data; > TargetFdDataFunc target_to_host_data; > + TargetFdAddrFunc target_to_host_addr; > } TargetFdTrans; > > static TargetFdTrans **target_fd_trans; > @@ -313,6 +315,14 @@ static TargetFdDataFunc fd_trans_host_to_target_data(int fd) > return NULL; > } > > +static TargetFdAddrFunc fd_trans_target_to_host_addr(int fd) > +{ > + if (fd < target_fd_max && target_fd_trans[fd]) { > + return target_fd_trans[fd]->target_to_host_addr; > + } > + return NULL; This should probably do something sensible with a negative input (either assert, or return NULL, I guess). > +} > + > static void fd_trans_register(int fd, TargetFdTrans *trans) > { > unsigned int oldmax; > @@ -2115,7 +2125,12 @@ static abi_long do_bind(int sockfd, abi_ulong target_addr, > > addr = alloca(addrlen+1); > > - ret = target_to_host_sockaddr(addr, target_addr, addrlen); > + if (fd_trans_target_to_host_addr(sockfd)) { > + ret = fd_trans_target_to_host_addr(sockfd)(addr, target_addr, > + addrlen); > + } else { > + ret = target_to_host_sockaddr(addr, target_addr, addrlen); > + } > if (ret) > return ret; > > @@ -2135,7 +2150,12 @@ static abi_long do_connect(int sockfd, abi_ulong target_addr, > > addr = alloca(addrlen+1); > > - ret = target_to_host_sockaddr(addr, target_addr, addrlen); > + if (fd_trans_target_to_host_addr(sockfd)) { > + ret = fd_trans_target_to_host_addr(sockfd)(addr, target_addr, > + addrlen); > + } else { > + ret = target_to_host_sockaddr(addr, target_addr, addrlen); > + } > if (ret) > return ret; > > @@ -2155,8 +2175,14 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp, > if (msgp->msg_name) { > msg.msg_namelen = tswap32(msgp->msg_namelen); > msg.msg_name = alloca(msg.msg_namelen+1); > - ret = target_to_host_sockaddr(msg.msg_name, tswapal(msgp->msg_name), > - msg.msg_namelen); > + if (fd_trans_target_to_host_addr(fd)) { > + ret = fd_trans_target_to_host_addr(fd)(msg.msg_name, > + tswapal(msgp->msg_name), > + msg.msg_namelen); > + } else { > + ret = target_to_host_sockaddr(msg.msg_name, tswapal(msgp->msg_name), > + msg.msg_namelen); > + } > if (ret) { > goto out2; > } > @@ -2418,7 +2444,12 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags, > return -TARGET_EFAULT; > if (target_addr) { > addr = alloca(addrlen+1); > - ret = target_to_host_sockaddr(addr, target_addr, addrlen); > + if (fd_trans_target_to_host_addr(fd)) { > + ret = fd_trans_target_to_host_addr(fd)(addr, target_addr, > + addrlen); > + } else { > + ret = target_to_host_sockaddr(addr, target_addr, addrlen); > + } > if (ret) { > unlock_user(host_msg, msg, 0); > return ret; The repetition here suggests we should pass the fd into target_to_host_sockaddr and do the handling of fd_trans_target_to_host_addr there. thanks -- PMM
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 41b85b4..31b5c2c 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -296,9 +296,11 @@ static bitmask_transtbl fcntl_flags_tbl[] = { }; typedef abi_long (*TargetFdDataFunc)(void *, size_t); +typedef abi_long (*TargetFdAddrFunc)(void *, abi_ulong, socklen_t); typedef struct TargetFdTrans { TargetFdDataFunc host_to_target_data; TargetFdDataFunc target_to_host_data; + TargetFdAddrFunc target_to_host_addr; } TargetFdTrans; static TargetFdTrans **target_fd_trans; @@ -313,6 +315,14 @@ static TargetFdDataFunc fd_trans_host_to_target_data(int fd) return NULL; } +static TargetFdAddrFunc fd_trans_target_to_host_addr(int fd) +{ + if (fd < target_fd_max && target_fd_trans[fd]) { + return target_fd_trans[fd]->target_to_host_addr; + } + return NULL; +} + static void fd_trans_register(int fd, TargetFdTrans *trans) { unsigned int oldmax; @@ -2115,7 +2125,12 @@ static abi_long do_bind(int sockfd, abi_ulong target_addr, addr = alloca(addrlen+1); - ret = target_to_host_sockaddr(addr, target_addr, addrlen); + if (fd_trans_target_to_host_addr(sockfd)) { + ret = fd_trans_target_to_host_addr(sockfd)(addr, target_addr, + addrlen); + } else { + ret = target_to_host_sockaddr(addr, target_addr, addrlen); + } if (ret) return ret; @@ -2135,7 +2150,12 @@ static abi_long do_connect(int sockfd, abi_ulong target_addr, addr = alloca(addrlen+1); - ret = target_to_host_sockaddr(addr, target_addr, addrlen); + if (fd_trans_target_to_host_addr(sockfd)) { + ret = fd_trans_target_to_host_addr(sockfd)(addr, target_addr, + addrlen); + } else { + ret = target_to_host_sockaddr(addr, target_addr, addrlen); + } if (ret) return ret; @@ -2155,8 +2175,14 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp, if (msgp->msg_name) { msg.msg_namelen = tswap32(msgp->msg_namelen); msg.msg_name = alloca(msg.msg_namelen+1); - ret = target_to_host_sockaddr(msg.msg_name, tswapal(msgp->msg_name), - msg.msg_namelen); + if (fd_trans_target_to_host_addr(fd)) { + ret = fd_trans_target_to_host_addr(fd)(msg.msg_name, + tswapal(msgp->msg_name), + msg.msg_namelen); + } else { + ret = target_to_host_sockaddr(msg.msg_name, tswapal(msgp->msg_name), + msg.msg_namelen); + } if (ret) { goto out2; } @@ -2418,7 +2444,12 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags, return -TARGET_EFAULT; if (target_addr) { addr = alloca(addrlen+1); - ret = target_to_host_sockaddr(addr, target_addr, addrlen); + if (fd_trans_target_to_host_addr(fd)) { + ret = fd_trans_target_to_host_addr(fd)(addr, target_addr, + addrlen); + } else { + ret = target_to_host_sockaddr(addr, target_addr, addrlen); + } if (ret) { unlock_user(host_msg, msg, 0); return ret;
Signed-off-by: Laurent Vivier <laurent@vivier.eu> --- linux-user/syscall.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-)