提交 cbb46f5f 编写于 作者: P Peter Maydell

Merge remote-tracking branch 'remotes/riku/linux-user-for-upstream' into staging

* remotes/riku/linux-user-for-upstream:
  linux-user: use TARGET_SA_ONSTACK in get_sigframe
  alloca one extra byte sockets
  linux-user: handle AF_PACKET sockaddrs in target_to_host_sockaddr
  qemu-user: Impl. setsockopt(SO_BINDTODEVICE)
  SIOCGIFINDEX: fix typo
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
...@@ -118,7 +118,7 @@ ...@@ -118,7 +118,7 @@
IOCTL(SIOCSIFMEM, IOC_W, MK_PTR(MK_STRUCT(STRUCT_ptr_ifreq))) IOCTL(SIOCSIFMEM, IOC_W, MK_PTR(MK_STRUCT(STRUCT_ptr_ifreq)))
IOCTL(SIOCADDMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) IOCTL(SIOCADDMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
IOCTL(SIOCDELMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) IOCTL(SIOCDELMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
IOCTL(SIOCGIFINDEX, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) IOCTL(SIOCGIFINDEX, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_int_ifreq)))
IOCTL(SIOCSIFLINK, 0, TYPE_NULL) IOCTL(SIOCSIFLINK, 0, TYPE_NULL)
IOCTL_SPECIAL(SIOCGIFCONF, IOC_W | IOC_R, do_ioctl_ifconf, IOCTL_SPECIAL(SIOCGIFCONF, IOC_W | IOC_R, do_ioctl_ifconf,
MK_PTR(MK_STRUCT(STRUCT_ifconf))) MK_PTR(MK_STRUCT(STRUCT_ifconf)))
......
...@@ -1305,7 +1305,7 @@ static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env) ...@@ -1305,7 +1305,7 @@ static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env)
/* /*
* This is the X/Open sanctioned signal stack switching. * This is the X/Open sanctioned signal stack switching.
*/ */
if ((ka->sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) { if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) {
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
} }
...@@ -3509,8 +3509,9 @@ static abi_ulong get_sigframe(struct target_sigaction *ka, ...@@ -3509,8 +3509,9 @@ static abi_ulong get_sigframe(struct target_sigaction *ka,
{ {
abi_ulong sp = env->regs[1]; abi_ulong sp = env->regs[1];
if ((ka->sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp)) if ((ka->sa_flags & TARGET_SA_ONSTACK) != 0 && !on_sig_stack(sp)) {
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
}
return ((sp - frame_size) & -8UL); return ((sp - frame_size) & -8UL);
} }
...@@ -3891,7 +3892,7 @@ static inline abi_ulong get_sigframe(struct target_sigaction *ka, ...@@ -3891,7 +3892,7 @@ static inline abi_ulong get_sigframe(struct target_sigaction *ka,
/* redzone */ /* redzone */
/* This is the X/Open sanctioned signal stack switching. */ /* This is the X/Open sanctioned signal stack switching. */
if ((ka->sa_flags & SA_ONSTACK) != 0 && !onsigstack) { if ((ka->sa_flags & TARGET_SA_ONSTACK) != 0 && !onsigstack) {
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
} }
......
...@@ -1140,6 +1140,13 @@ static inline abi_long target_to_host_sockaddr(struct sockaddr *addr, ...@@ -1140,6 +1140,13 @@ static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
memcpy(addr, target_saddr, len); memcpy(addr, target_saddr, len);
addr->sa_family = sa_family; addr->sa_family = sa_family;
if (sa_family == AF_PACKET) {
struct target_sockaddr_ll *lladdr;
lladdr = (struct target_sockaddr_ll *)addr;
lladdr->sll_ifindex = tswap32(lladdr->sll_ifindex);
lladdr->sll_hatype = tswap16(lladdr->sll_hatype);
}
unlock_user(target_saddr, target_addr, 0); unlock_user(target_saddr, target_addr, 0);
return 0; return 0;
...@@ -1497,6 +1504,25 @@ set_timeout: ...@@ -1497,6 +1504,25 @@ set_timeout:
unlock_user_struct(tfprog, optval_addr, 1); unlock_user_struct(tfprog, optval_addr, 1);
return ret; return ret;
} }
case TARGET_SO_BINDTODEVICE:
{
char *dev_ifname, *addr_ifname;
if (optlen > IFNAMSIZ - 1) {
optlen = IFNAMSIZ - 1;
}
dev_ifname = lock_user(VERIFY_READ, optval_addr, optlen, 1);
if (!dev_ifname) {
return -TARGET_EFAULT;
}
optname = SO_BINDTODEVICE;
addr_ifname = alloca(IFNAMSIZ);
memcpy(addr_ifname, dev_ifname, optlen);
addr_ifname[optlen] = 0;
ret = get_errno(setsockopt(sockfd, level, optname, addr_ifname, optlen));
unlock_user (dev_ifname, optval_addr, 0);
return ret;
}
/* Options with 'int' argument. */ /* Options with 'int' argument. */
case TARGET_SO_DEBUG: case TARGET_SO_DEBUG:
optname = SO_DEBUG; optname = SO_DEBUG;
...@@ -1958,7 +1984,7 @@ static abi_long do_connect(int sockfd, abi_ulong target_addr, ...@@ -1958,7 +1984,7 @@ static abi_long do_connect(int sockfd, abi_ulong target_addr,
return -TARGET_EINVAL; return -TARGET_EINVAL;
} }
addr = alloca(addrlen); addr = alloca(addrlen+1);
ret = target_to_host_sockaddr(addr, target_addr, addrlen); ret = target_to_host_sockaddr(addr, target_addr, addrlen);
if (ret) if (ret)
...@@ -1979,7 +2005,7 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp, ...@@ -1979,7 +2005,7 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
if (msgp->msg_name) { if (msgp->msg_name) {
msg.msg_namelen = tswap32(msgp->msg_namelen); msg.msg_namelen = tswap32(msgp->msg_namelen);
msg.msg_name = alloca(msg.msg_namelen); msg.msg_name = alloca(msg.msg_namelen+1);
ret = target_to_host_sockaddr(msg.msg_name, tswapal(msgp->msg_name), ret = target_to_host_sockaddr(msg.msg_name, tswapal(msgp->msg_name),
msg.msg_namelen); msg.msg_namelen);
if (ret) { if (ret) {
...@@ -2242,7 +2268,7 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags, ...@@ -2242,7 +2268,7 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
if (!host_msg) if (!host_msg)
return -TARGET_EFAULT; return -TARGET_EFAULT;
if (target_addr) { if (target_addr) {
addr = alloca(addrlen); addr = alloca(addrlen+1);
ret = target_to_host_sockaddr(addr, target_addr, addrlen); ret = target_to_host_sockaddr(addr, target_addr, addrlen);
if (ret) { if (ret) {
unlock_user(host_msg, msg, 0); unlock_user(host_msg, msg, 0);
......
...@@ -121,6 +121,16 @@ struct target_sockaddr { ...@@ -121,6 +121,16 @@ struct target_sockaddr {
uint8_t sa_data[14]; uint8_t sa_data[14];
}; };
struct target_sockaddr_ll {
uint16_t sll_family; /* Always AF_PACKET */
uint16_t sll_protocol; /* Physical layer protocol */
int sll_ifindex; /* Interface number */
uint16_t sll_hatype; /* ARP hardware type */
uint8_t sll_pkttype; /* Packet type */
uint8_t sll_halen; /* Length of address */
uint8_t sll_addr[8]; /* Physical layer address */
};
struct target_sock_filter { struct target_sock_filter {
abi_ushort code; abi_ushort code;
uint8_t jt; uint8_t jt;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册