diff options
author | Laurent Vivier <laurent@vivier.eu> | 2015-10-28 21:40:44 +0100 |
---|---|---|
committer | Timothy Pearson <tpearson@raptorengineering.com> | 2019-11-29 19:28:22 -0600 |
commit | 4619ad70f49bd13ed4776059cadf2a4151d28c1c (patch) | |
tree | 4121c2c45918854df65d81d46d9d2818ddc31621 | |
parent | 607a7019b8cc9d08c683fdd53b6f29118ec3fea5 (diff) | |
download | hqemu-4619ad70f49bd13ed4776059cadf2a4151d28c1c.zip hqemu-4619ad70f49bd13ed4776059cadf2a4151d28c1c.tar.gz |
linux-user: add a function hook to translate sockaddr
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
-rw-r--r-- | linux-user/syscall.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 47a0007..6305dd3 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -297,9 +297,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; @@ -314,6 +316,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; @@ -1163,7 +1173,7 @@ static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn, return 0; } -static inline abi_long target_to_host_sockaddr(struct sockaddr *addr, +static inline abi_long target_to_host_sockaddr(int fd, struct sockaddr *addr, abi_ulong target_addr, socklen_t len) { @@ -1171,6 +1181,10 @@ static inline abi_long target_to_host_sockaddr(struct sockaddr *addr, sa_family_t sa_family; struct target_sockaddr *target_saddr; + if (fd_trans_target_to_host_addr(fd)) { + return fd_trans_target_to_host_addr(fd)(addr, target_addr, len); + } + target_saddr = lock_user(VERIFY_READ, target_addr, len, 1); if (!target_saddr) return -TARGET_EFAULT; @@ -2116,7 +2130,7 @@ static abi_long do_bind(int sockfd, abi_ulong target_addr, addr = alloca(addrlen+1); - ret = target_to_host_sockaddr(addr, target_addr, addrlen); + ret = target_to_host_sockaddr(sockfd, addr, target_addr, addrlen); if (ret) return ret; @@ -2136,7 +2150,7 @@ static abi_long do_connect(int sockfd, abi_ulong target_addr, addr = alloca(addrlen+1); - ret = target_to_host_sockaddr(addr, target_addr, addrlen); + ret = target_to_host_sockaddr(sockfd, addr, target_addr, addrlen); if (ret) return ret; @@ -2156,8 +2170,9 @@ 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); + ret = target_to_host_sockaddr(fd, msg.msg_name, + tswapal(msgp->msg_name), + msg.msg_namelen); if (ret) { goto out2; } @@ -2419,7 +2434,7 @@ 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); + ret = target_to_host_sockaddr(fd, addr, target_addr, addrlen); if (ret) { unlock_user(host_msg, msg, 0); return ret; |