提交 9f9a03b9 编写于 作者: A Anthony Liguori

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

# By Andreas Schwab (2) and others
# Via Riku Voipio
* riku/linux-user-for-upstream:
  linux-user: Do not ignore mmap failure from host
  linux-user: improve target_to_host_sock_type conversion
  user-exec.c: Set is_write correctly in the ARM cpu_signal_handler()
  linux-user: Fix sys_utimensat (would not compile on old glibc)
  linux-user: fix signal number range check
  linux-user: add SIOCADDRT/SIOCDELRT support
  linux-user: handle /proc/$$ like /proc/self

Message-id: cover.1373051589.git.riku.voipio@linaro.org
Signed-off-by: NAnthony Liguori <aliguori@us.ibm.com>
...@@ -88,8 +88,6 @@ ...@@ -88,8 +88,6 @@
#endif #endif
IOCTL(SIOCATMARK, 0, TYPE_NULL) IOCTL(SIOCATMARK, 0, TYPE_NULL)
IOCTL(SIOCADDRT, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtentry)))
IOCTL(SIOCDELRT, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtentry)))
IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT)) IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT))
IOCTL(SIOCGIFFLAGS, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_short_ifreq))) IOCTL(SIOCGIFFLAGS, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
IOCTL(SIOCSIFFLAGS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_short_ifreq))) IOCTL(SIOCSIFFLAGS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
...@@ -379,3 +377,7 @@ ...@@ -379,3 +377,7 @@
MK_PTR(MK_STRUCT(STRUCT_dm_ioctl))) MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
IOCTL_SPECIAL(DM_DEV_SET_GEOMETRY, IOC_RW, do_ioctl_dm, IOCTL_SPECIAL(DM_DEV_SET_GEOMETRY, IOC_RW, do_ioctl_dm,
MK_PTR(MK_STRUCT(STRUCT_dm_ioctl))) MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
IOCTL_SPECIAL(SIOCADDRT, IOC_W, do_ioctl_rt,
MK_PTR(MK_STRUCT(STRUCT_rtentry)))
IOCTL_SPECIAL(SIOCDELRT, IOC_W, do_ioctl_rt,
MK_PTR(MK_STRUCT(STRUCT_rtentry)))
...@@ -483,6 +483,10 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, ...@@ -483,6 +483,10 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
if (!(flags & MAP_ANONYMOUS)) { if (!(flags & MAP_ANONYMOUS)) {
p = mmap(g2h(start), len, prot, p = mmap(g2h(start), len, prot,
flags | MAP_FIXED, fd, host_offset); flags | MAP_FIXED, fd, host_offset);
if (p == MAP_FAILED) {
munmap(g2h(start), host_len);
goto fail;
}
host_start += offset - host_offset; host_start += offset - host_offset;
} }
start = h2g(host_start); start = h2g(host_start);
......
...@@ -102,14 +102,14 @@ static inline int sas_ss_flags(unsigned long sp) ...@@ -102,14 +102,14 @@ static inline int sas_ss_flags(unsigned long sp)
int host_to_target_signal(int sig) int host_to_target_signal(int sig)
{ {
if (sig >= _NSIG) if (sig < 0 || sig >= _NSIG)
return sig; return sig;
return host_to_target_signal_table[sig]; return host_to_target_signal_table[sig];
} }
int target_to_host_signal(int sig) int target_to_host_signal(int sig)
{ {
if (sig >= _NSIG) if (sig < 0 || sig >= _NSIG)
return sig; return sig;
return target_to_host_signal_table[sig]; return target_to_host_signal_table[sig];
} }
......
#if defined(TARGET_MIPS) #if defined(TARGET_MIPS)
// MIPS special values for constants /* MIPS special values for constants */
/* /*
* For setsockopt(2) * For setsockopt(2)
* *
* This defines are ABI conformant as far as Linux supports these ... * This defines are ABI conformant as far as Linux supports these ...
*/ */
#define TARGET_SOL_SOCKET 0xffff #define TARGET_SOL_SOCKET 0xffff
#define TARGET_SO_DEBUG 0x0001 /* Record debugging information. */ #define TARGET_SO_DEBUG 0x0001 /* Record debugging information. */
#define TARGET_SO_REUSEADDR 0x0004 /* Allow reuse of local addresses. */ #define TARGET_SO_REUSEADDR 0x0004 /* Allow reuse of local addresses. */
#define TARGET_SO_KEEPALIVE 0x0008 /* Keep connections alive and send #define TARGET_SO_KEEPALIVE 0x0008 /* Keep connections alive and send
SIGPIPE when they die. */ SIGPIPE when they die. */
#define TARGET_SO_DONTROUTE 0x0010 /* Don't do local routing. */ #define TARGET_SO_DONTROUTE 0x0010 /* Don't do local routing. */
#define TARGET_SO_BROADCAST 0x0020 /* Allow transmission of #define TARGET_SO_BROADCAST 0x0020 /* Allow transmission of
broadcast messages. */ broadcast messages. */
#define TARGET_SO_LINGER 0x0080 /* Block on close of a reliable #define TARGET_SO_LINGER 0x0080 /* Block on close of a reliable
socket to transmit pending data. */ * socket to transmit pending data.
#define TARGET_SO_OOBINLINE 0x0100 /* Receive out-of-band data in-band. */ */
#if 0 #define TARGET_SO_OOBINLINE 0x0100 /* Receive out-of-band data in-band.
To add: #define TARGET_SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */ */
#endif #if 0
/* To add: Allow local address and port reuse. */
#define TARGET_SO_TYPE 0x1008 /* Compatible name for SO_STYLE. */ #define TARGET_SO_REUSEPORT 0x0200
#define TARGET_SO_STYLE SO_TYPE /* Synonym */ #endif
#define TARGET_SO_ERROR 0x1007 /* get error status and clear */
#define TARGET_SO_SNDBUF 0x1001 /* Send buffer size. */ #define TARGET_SO_TYPE 0x1008 /* Compatible name for SO_STYLE. */
#define TARGET_SO_RCVBUF 0x1002 /* Receive buffer. */ #define TARGET_SO_STYLE SO_TYPE /* Synonym */
#define TARGET_SO_SNDLOWAT 0x1003 /* send low-water mark */ #define TARGET_SO_ERROR 0x1007 /* get error status and clear */
#define TARGET_SO_RCVLOWAT 0x1004 /* receive low-water mark */ #define TARGET_SO_SNDBUF 0x1001 /* Send buffer size. */
#define TARGET_SO_SNDTIMEO 0x1005 /* send timeout */ #define TARGET_SO_RCVBUF 0x1002 /* Receive buffer. */
#define TARGET_SO_RCVTIMEO 0x1006 /* receive timeout */ #define TARGET_SO_SNDLOWAT 0x1003 /* send low-water mark */
#define TARGET_SO_ACCEPTCONN 0x1009 #define TARGET_SO_RCVLOWAT 0x1004 /* receive low-water mark */
#define TARGET_SO_SNDTIMEO 0x1005 /* send timeout */
/* linux-specific, might as well be the same as on i386 */ #define TARGET_SO_RCVTIMEO 0x1006 /* receive timeout */
#define TARGET_SO_NO_CHECK 11 #define TARGET_SO_ACCEPTCONN 0x1009
#define TARGET_SO_PRIORITY 12
#define TARGET_SO_BSDCOMPAT 14 /* linux-specific, might as well be the same as on i386 */
#define TARGET_SO_NO_CHECK 11
#define TARGET_SO_PASSCRED 17 #define TARGET_SO_PRIORITY 12
#define TARGET_SO_PEERCRED 18 #define TARGET_SO_BSDCOMPAT 14
/* Security levels - as per NRL IPv6 - don't actually do anything */ #define TARGET_SO_PASSCRED 17
#define TARGET_SO_SECURITY_AUTHENTICATION 22 #define TARGET_SO_PEERCRED 18
#define TARGET_SO_SECURITY_ENCRYPTION_TRANSPORT 23
#define TARGET_SO_SECURITY_ENCRYPTION_NETWORK 24 /* Security levels - as per NRL IPv6 - don't actually do anything */
#define TARGET_SO_SECURITY_AUTHENTICATION 22
#define TARGET_SO_BINDTODEVICE 25 #define TARGET_SO_SECURITY_ENCRYPTION_TRANSPORT 23
#define TARGET_SO_SECURITY_ENCRYPTION_NETWORK 24
/* Socket filtering */
#define TARGET_SO_ATTACH_FILTER 26 #define TARGET_SO_BINDTODEVICE 25
#define TARGET_SO_DETACH_FILTER 27
/* Socket filtering */
#define TARGET_SO_PEERNAME 28 #define TARGET_SO_ATTACH_FILTER 26
#define TARGET_SO_TIMESTAMP 29 #define TARGET_SO_DETACH_FILTER 27
#define SCM_TIMESTAMP SO_TIMESTAMP
#define TARGET_SO_PEERNAME 28
#define TARGET_SO_PEERSEC 30 #define TARGET_SO_TIMESTAMP 29
#define TARGET_SO_SNDBUFFORCE 31 #define SCM_TIMESTAMP SO_TIMESTAMP
#define TARGET_SO_RCVBUFFORCE 33
#define TARGET_SO_PEERSEC 30
/** sock_type - Socket types #define TARGET_SO_SNDBUFFORCE 31
* #define TARGET_SO_RCVBUFFORCE 33
* Please notice that for binary compat reasons MIPS has to
* override the enum sock_type in include/linux/net.h, so /** sock_type - Socket types
* we define ARCH_HAS_SOCKET_TYPES here. *
* * Please notice that for binary compat reasons MIPS has to
* @SOCK_DGRAM - datagram (conn.less) socket * override the enum sock_type in include/linux/net.h, so
* @SOCK_STREAM - stream (connection) socket * we define ARCH_HAS_SOCKET_TYPES here.
* @SOCK_RAW - raw socket *
* @SOCK_RDM - reliably-delivered message * @SOCK_DGRAM - datagram (conn.less) socket
* @SOCK_SEQPACKET - sequential packet socket * @SOCK_STREAM - stream (connection) socket
* @SOCK_PACKET - linux specific way of getting packets at the dev level. * @SOCK_RAW - raw socket
* For writing rarp and other similar things on the user level. * @SOCK_RDM - reliably-delivered message
*/ * @SOCK_SEQPACKET - sequential packet socket
enum sock_type { * @SOCK_DCCP - Datagram Congestion Control Protocol socket
TARGET_SOCK_DGRAM = 1, * @SOCK_PACKET - linux specific way of getting packets at the dev level.
TARGET_SOCK_STREAM = 2, * For writing rarp and other similar things on the user
TARGET_SOCK_RAW = 3, * level.
TARGET_SOCK_RDM = 4, * @SOCK_CLOEXEC - sets the close-on-exec (FD_CLOEXEC) flag.
TARGET_SOCK_SEQPACKET = 5, * @SOCK_NONBLOCK - sets the O_NONBLOCK file status flag.
TARGET_SOCK_DCCP = 6, */
TARGET_SOCK_PACKET = 10,
}; #define ARCH_HAS_SOCKET_TYPES 1
#define TARGET_SOCK_MAX (SOCK_PACKET + 1) enum sock_type {
TARGET_SOCK_DGRAM = 1,
TARGET_SOCK_STREAM = 2,
TARGET_SOCK_RAW = 3,
TARGET_SOCK_RDM = 4,
TARGET_SOCK_SEQPACKET = 5,
TARGET_SOCK_DCCP = 6,
TARGET_SOCK_PACKET = 10,
TARGET_SOCK_CLOEXEC = 02000000,
TARGET_SOCK_NONBLOCK = 0200,
};
#define TARGET_SOCK_MAX (TARGET_SOCK_PACKET + 1)
#define TARGET_SOCK_TYPE_MASK 0xf /* Covers up to TARGET_SOCK_MAX-1. */
#elif defined(TARGET_ALPHA) #elif defined(TARGET_ALPHA)
...@@ -156,61 +169,167 @@ ...@@ -156,61 +169,167 @@
/* Instruct lower device to use last 4-bytes of skb data as FCS */ /* Instruct lower device to use last 4-bytes of skb data as FCS */
#define TARGET_SO_NOFCS 43 #define TARGET_SO_NOFCS 43
/** sock_type - Socket types
*
* Please notice that for binary compat reasons ALPHA has to
* override the enum sock_type in include/linux/net.h, so
* we define ARCH_HAS_SOCKET_TYPES here.
*
* @SOCK_DGRAM - datagram (conn.less) socket
* @SOCK_STREAM - stream (connection) socket
* @SOCK_RAW - raw socket
* @SOCK_RDM - reliably-delivered message
* @SOCK_SEQPACKET - sequential packet socket
* @SOCK_DCCP - Datagram Congestion Control Protocol socket
* @SOCK_PACKET - linux specific way of getting packets at the dev level.
* For writing rarp and other similar things on the user
* level.
* @SOCK_CLOEXEC - sets the close-on-exec (FD_CLOEXEC) flag.
* @SOCK_NONBLOCK - sets the O_NONBLOCK file status flag.
*/
#define ARCH_HAS_SOCKET_TYPES 1
enum sock_type {
TARGET_SOCK_STREAM = 1,
TARGET_SOCK_DGRAM = 2,
TARGET_SOCK_RAW = 3,
TARGET_SOCK_RDM = 4,
TARGET_SOCK_SEQPACKET = 5,
TARGET_SOCK_DCCP = 6,
TARGET_SOCK_PACKET = 10,
TARGET_SOCK_CLOEXEC = 010000000,
TARGET_SOCK_NONBLOCK = 010000000000,
};
#define TARGET_SOCK_MAX (TARGET_SOCK_PACKET + 1)
#define TARGET_SOCK_TYPE_MASK 0xf /* Covers up to TARGET_SOCK_MAX-1. */
#else #else
/* For setsockopt(2) */ #if defined(TARGET_SPARC)
#define TARGET_SOL_SOCKET 1 /** sock_type - Socket types
*
#define TARGET_SO_DEBUG 1 * Please notice that for binary compat reasons SPARC has to
#define TARGET_SO_REUSEADDR 2 * override the enum sock_type in include/linux/net.h, so
#define TARGET_SO_TYPE 3 * we define ARCH_HAS_SOCKET_TYPES here.
#define TARGET_SO_ERROR 4 *
#define TARGET_SO_DONTROUTE 5 * @SOCK_DGRAM - datagram (conn.less) socket
#define TARGET_SO_BROADCAST 6 * @SOCK_STREAM - stream (connection) socket
#define TARGET_SO_SNDBUF 7 * @SOCK_RAW - raw socket
#define TARGET_SO_RCVBUF 8 * @SOCK_RDM - reliably-delivered message
#define TARGET_SO_SNDBUFFORCE 32 * @SOCK_SEQPACKET - sequential packet socket
#define TARGET_SO_RCVBUFFORCE 33 * @SOCK_DCCP - Datagram Congestion Control Protocol socket
#define TARGET_SO_KEEPALIVE 9 * @SOCK_PACKET - linux specific way of getting packets at the dev level.
#define TARGET_SO_OOBINLINE 10 * For writing rarp and other similar things on the user
#define TARGET_SO_NO_CHECK 11 * level.
#define TARGET_SO_PRIORITY 12 * @SOCK_CLOEXEC - sets the close-on-exec (FD_CLOEXEC) flag.
#define TARGET_SO_LINGER 13 * @SOCK_NONBLOCK - sets the O_NONBLOCK file status flag.
#define TARGET_SO_BSDCOMPAT 14 */
/* To add :#define TARGET_SO_REUSEPORT 15 */
#define ARCH_HAS_SOCKET_TYPES 1
enum sock_type {
TARGET_SOCK_STREAM = 1,
TARGET_SOCK_DGRAM = 2,
TARGET_SOCK_RAW = 3,
TARGET_SOCK_RDM = 4,
TARGET_SOCK_SEQPACKET = 5,
TARGET_SOCK_DCCP = 6,
TARGET_SOCK_PACKET = 10,
TARGET_SOCK_CLOEXEC = 020000000,
TARGET_SOCK_NONBLOCK = 040000,
};
#define TARGET_SOCK_MAX (TARGET_SOCK_PACKET + 1)
#define TARGET_SOCK_TYPE_MASK 0xf /* Covers up to TARGET_SOCK_MAX-1. */
#endif
/* For setsockopt(2) */
#define TARGET_SOL_SOCKET 1
#define TARGET_SO_DEBUG 1
#define TARGET_SO_REUSEADDR 2
#define TARGET_SO_TYPE 3
#define TARGET_SO_ERROR 4
#define TARGET_SO_DONTROUTE 5
#define TARGET_SO_BROADCAST 6
#define TARGET_SO_SNDBUF 7
#define TARGET_SO_RCVBUF 8
#define TARGET_SO_SNDBUFFORCE 32
#define TARGET_SO_RCVBUFFORCE 33
#define TARGET_SO_KEEPALIVE 9
#define TARGET_SO_OOBINLINE 10
#define TARGET_SO_NO_CHECK 11
#define TARGET_SO_PRIORITY 12
#define TARGET_SO_LINGER 13
#define TARGET_SO_BSDCOMPAT 14
/* To add :#define TARGET_SO_REUSEPORT 15 */
#if defined(TARGET_PPC) #if defined(TARGET_PPC)
#define TARGET_SO_RCVLOWAT 16 #define TARGET_SO_RCVLOWAT 16
#define TARGET_SO_SNDLOWAT 17 #define TARGET_SO_SNDLOWAT 17
#define TARGET_SO_RCVTIMEO 18 #define TARGET_SO_RCVTIMEO 18
#define TARGET_SO_SNDTIMEO 19 #define TARGET_SO_SNDTIMEO 19
#define TARGET_SO_PASSCRED 20 #define TARGET_SO_PASSCRED 20
#define TARGET_SO_PEERCRED 21 #define TARGET_SO_PEERCRED 21
#else #else
#define TARGET_SO_PASSCRED 16 #define TARGET_SO_PASSCRED 16
#define TARGET_SO_PEERCRED 17 #define TARGET_SO_PEERCRED 17
#define TARGET_SO_RCVLOWAT 18 #define TARGET_SO_RCVLOWAT 18
#define TARGET_SO_SNDLOWAT 19 #define TARGET_SO_SNDLOWAT 19
#define TARGET_SO_RCVTIMEO 20 #define TARGET_SO_RCVTIMEO 20
#define TARGET_SO_SNDTIMEO 21 #define TARGET_SO_SNDTIMEO 21
#endif #endif
/* Security levels - as per NRL IPv6 - don't actually do anything */ /* Security levels - as per NRL IPv6 - don't actually do anything */
#define TARGET_SO_SECURITY_AUTHENTICATION 22 #define TARGET_SO_SECURITY_AUTHENTICATION 22
#define TARGET_SO_SECURITY_ENCRYPTION_TRANSPORT 23 #define TARGET_SO_SECURITY_ENCRYPTION_TRANSPORT 23
#define TARGET_SO_SECURITY_ENCRYPTION_NETWORK 24 #define TARGET_SO_SECURITY_ENCRYPTION_NETWORK 24
#define TARGET_SO_BINDTODEVICE 25 #define TARGET_SO_BINDTODEVICE 25
/* Socket filtering */ /* Socket filtering */
#define TARGET_SO_ATTACH_FILTER 26 #define TARGET_SO_ATTACH_FILTER 26
#define TARGET_SO_DETACH_FILTER 27 #define TARGET_SO_DETACH_FILTER 27
#define TARGET_SO_PEERNAME 28
#define TARGET_SO_TIMESTAMP 29
#define TARGET_SCM_TIMESTAMP TARGET_SO_TIMESTAMP
#define TARGET_SO_PEERNAME 28 #define TARGET_SO_ACCEPTCONN 30
#define TARGET_SO_TIMESTAMP 29
#define TARGET_SCM_TIMESTAMP TARGET_SO_TIMESTAMP
#define TARGET_SO_ACCEPTCONN 30 #define TARGET_SO_PEERSEC 31
#endif
#define TARGET_SO_PEERSEC 31 #ifndef ARCH_HAS_SOCKET_TYPES
/** sock_type - Socket types - default values
*
*
* @SOCK_STREAM - stream (connection) socket
* @SOCK_DGRAM - datagram (conn.less) socket
* @SOCK_RAW - raw socket
* @SOCK_RDM - reliably-delivered message
* @SOCK_SEQPACKET - sequential packet socket
* @SOCK_DCCP - Datagram Congestion Control Protocol socket
* @SOCK_PACKET - linux specific way of getting packets at the dev level.
* For writing rarp and other similar things on the user
* level.
* @SOCK_CLOEXEC - sets the close-on-exec (FD_CLOEXEC) flag.
* @SOCK_NONBLOCK - sets the O_NONBLOCK file status flag.
*/
enum sock_type {
TARGET_SOCK_STREAM = 1,
TARGET_SOCK_DGRAM = 2,
TARGET_SOCK_RAW = 3,
TARGET_SOCK_RDM = 4,
TARGET_SOCK_SEQPACKET = 5,
TARGET_SOCK_DCCP = 6,
TARGET_SOCK_PACKET = 10,
TARGET_SOCK_CLOEXEC = 02000000,
TARGET_SOCK_NONBLOCK = 04000,
};
#define TARGET_SOCK_MAX (TARGET_SOCK_PACKET + 1)
#define TARGET_SOCK_TYPE_MASK 0xf /* Covers up to TARGET_SOCK_MAX-1. */
#endif #endif
...@@ -105,6 +105,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base, ...@@ -105,6 +105,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
#include <linux/vt.h> #include <linux/vt.h>
#include <linux/dm-ioctl.h> #include <linux/dm-ioctl.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/route.h>
#include "linux_loop.h" #include "linux_loop.h"
#include "cpu-uname.h" #include "cpu-uname.h"
...@@ -338,6 +339,7 @@ static int sys_openat(int dirfd, const char *pathname, int flags, mode_t mode) ...@@ -338,6 +339,7 @@ static int sys_openat(int dirfd, const char *pathname, int flags, mode_t mode)
} }
#endif #endif
#ifdef TARGET_NR_utimensat
#ifdef CONFIG_UTIMENSAT #ifdef CONFIG_UTIMENSAT
static int sys_utimensat(int dirfd, const char *pathname, static int sys_utimensat(int dirfd, const char *pathname,
const struct timespec times[2], int flags) const struct timespec times[2], int flags)
...@@ -347,12 +349,19 @@ static int sys_utimensat(int dirfd, const char *pathname, ...@@ -347,12 +349,19 @@ static int sys_utimensat(int dirfd, const char *pathname,
else else
return utimensat(dirfd, pathname, times, flags); return utimensat(dirfd, pathname, times, flags);
} }
#else #elif defined(__NR_utimensat)
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat) #define __NR_sys_utimensat __NR_utimensat
_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname, _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
const struct timespec *,tsp,int,flags) const struct timespec *,tsp,int,flags)
#else
static int sys_utimensat(int dirfd, const char *pathname,
const struct timespec times[2], int flags)
{
errno = ENOSYS;
return -1;
}
#endif #endif
#endif /* CONFIG_UTIMENSAT */ #endif /* TARGET_NR_utimensat */
#ifdef CONFIG_INOTIFY #ifdef CONFIG_INOTIFY
#include <sys/inotify.h> #include <sys/inotify.h>
...@@ -1696,31 +1705,36 @@ static void unlock_iovec(struct iovec *vec, abi_ulong target_addr, ...@@ -1696,31 +1705,36 @@ static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
free(vec); free(vec);
} }
/* do_socket() Must return target values and target errnos. */ static inline void target_to_host_sock_type(int *type)
static abi_long do_socket(int domain, int type, int protocol)
{ {
#if defined(TARGET_MIPS) int host_type = 0;
switch(type) { int target_type = *type;
switch (target_type & TARGET_SOCK_TYPE_MASK) {
case TARGET_SOCK_DGRAM: case TARGET_SOCK_DGRAM:
type = SOCK_DGRAM; host_type = SOCK_DGRAM;
break; break;
case TARGET_SOCK_STREAM: case TARGET_SOCK_STREAM:
type = SOCK_STREAM; host_type = SOCK_STREAM;
break;
case TARGET_SOCK_RAW:
type = SOCK_RAW;
break; break;
case TARGET_SOCK_RDM: default:
type = SOCK_RDM; host_type = target_type & TARGET_SOCK_TYPE_MASK;
break;
case TARGET_SOCK_SEQPACKET:
type = SOCK_SEQPACKET;
break;
case TARGET_SOCK_PACKET:
type = SOCK_PACKET;
break; break;
} }
#endif if (target_type & TARGET_SOCK_CLOEXEC) {
host_type |= SOCK_CLOEXEC;
}
if (target_type & TARGET_SOCK_NONBLOCK) {
host_type |= SOCK_NONBLOCK;
}
*type = host_type;
}
/* do_socket() Must return target values and target errnos. */
static abi_long do_socket(int domain, int type, int protocol)
{
target_to_host_sock_type(&type);
if (domain == PF_NETLINK) if (domain == PF_NETLINK)
return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */ return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
return get_errno(socket(domain, type, protocol)); return get_errno(socket(domain, type, protocol));
...@@ -1953,6 +1967,8 @@ static abi_long do_socketpair(int domain, int type, int protocol, ...@@ -1953,6 +1967,8 @@ static abi_long do_socketpair(int domain, int type, int protocol,
int tab[2]; int tab[2];
abi_long ret; abi_long ret;
target_to_host_sock_type(&type);
ret = get_errno(socketpair(domain, type, protocol, tab)); ret = get_errno(socketpair(domain, type, protocol, tab));
if (!is_error(ret)) { if (!is_error(ret)) {
if (put_user_s32(tab[0], target_tab_addr) if (put_user_s32(tab[0], target_tab_addr)
...@@ -3551,6 +3567,69 @@ out: ...@@ -3551,6 +3567,69 @@ out:
return ret; return ret;
} }
static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
int fd, abi_long cmd, abi_long arg)
{
const argtype *arg_type = ie->arg_type;
const StructEntry *se;
const argtype *field_types;
const int *dst_offsets, *src_offsets;
int target_size;
void *argptr;
abi_ulong *target_rt_dev_ptr;
unsigned long *host_rt_dev_ptr;
abi_long ret;
int i;
assert(ie->access == IOC_W);
assert(*arg_type == TYPE_PTR);
arg_type++;
assert(*arg_type == TYPE_STRUCT);
target_size = thunk_type_size(arg_type, 0);
argptr = lock_user(VERIFY_READ, arg, target_size, 1);
if (!argptr) {
return -TARGET_EFAULT;
}
arg_type++;
assert(*arg_type == (int)STRUCT_rtentry);
se = struct_entries + *arg_type++;
assert(se->convert[0] == NULL);
/* convert struct here to be able to catch rt_dev string */
field_types = se->field_types;
dst_offsets = se->field_offsets[THUNK_HOST];
src_offsets = se->field_offsets[THUNK_TARGET];
for (i = 0; i < se->nb_fields; i++) {
if (dst_offsets[i] == offsetof(struct rtentry, rt_dev)) {
assert(*field_types == TYPE_PTRVOID);
target_rt_dev_ptr = (abi_ulong *)(argptr + src_offsets[i]);
host_rt_dev_ptr = (unsigned long *)(buf_temp + dst_offsets[i]);
if (*target_rt_dev_ptr != 0) {
*host_rt_dev_ptr = (unsigned long)lock_user_string(
tswapal(*target_rt_dev_ptr));
if (!*host_rt_dev_ptr) {
unlock_user(argptr, arg, 0);
return -TARGET_EFAULT;
}
} else {
*host_rt_dev_ptr = 0;
}
field_types++;
continue;
}
field_types = thunk_convert(buf_temp + dst_offsets[i],
argptr + src_offsets[i],
field_types, THUNK_HOST);
}
unlock_user(argptr, arg, 0);
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
if (*host_rt_dev_ptr != 0) {
unlock_user((void *)*host_rt_dev_ptr,
*target_rt_dev_ptr, 0);
}
return ret;
}
static IOCTLEntry ioctl_entries[] = { static IOCTLEntry ioctl_entries[] = {
#define IOCTL(cmd, access, ...) \ #define IOCTL(cmd, access, ...) \
{ TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } }, { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
...@@ -4973,6 +5052,30 @@ static int open_self_auxv(void *cpu_env, int fd) ...@@ -4973,6 +5052,30 @@ static int open_self_auxv(void *cpu_env, int fd)
return 0; return 0;
} }
static int is_proc_myself(const char *filename, const char *entry)
{
if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
filename += strlen("/proc/");
if (!strncmp(filename, "self/", strlen("self/"))) {
filename += strlen("self/");
} else if (*filename >= '1' && *filename <= '9') {
char myself[80];
snprintf(myself, sizeof(myself), "%d/", getpid());
if (!strncmp(filename, myself, strlen(myself))) {
filename += strlen(myself);
} else {
return 0;
}
} else {
return 0;
}
if (!strcmp(filename, entry)) {
return 1;
}
}
return 0;
}
static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode) static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
{ {
struct fake_open { struct fake_open {
...@@ -4981,15 +5084,14 @@ static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode) ...@@ -4981,15 +5084,14 @@ static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
}; };
const struct fake_open *fake_open; const struct fake_open *fake_open;
static const struct fake_open fakes[] = { static const struct fake_open fakes[] = {
{ "/proc/self/maps", open_self_maps }, { "maps", open_self_maps },
{ "/proc/self/stat", open_self_stat }, { "stat", open_self_stat },
{ "/proc/self/auxv", open_self_auxv }, { "auxv", open_self_auxv },
{ NULL, NULL } { NULL, NULL }
}; };
for (fake_open = fakes; fake_open->filename; fake_open++) { for (fake_open = fakes; fake_open->filename; fake_open++) {
if (!strncmp(pathname, fake_open->filename, if (is_proc_myself(pathname, fake_open->filename)) {
strlen(fake_open->filename))) {
break; break;
} }
} }
...@@ -6262,20 +6364,18 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ...@@ -6262,20 +6364,18 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
#endif #endif
case TARGET_NR_readlink: case TARGET_NR_readlink:
{ {
void *p2, *temp; void *p2;
p = lock_user_string(arg1); p = lock_user_string(arg1);
p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0); p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
if (!p || !p2) if (!p || !p2) {
ret = -TARGET_EFAULT; ret = -TARGET_EFAULT;
else { } else if (is_proc_myself((const char *)p, "exe")) {
if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) { char real[PATH_MAX], *temp;
char real[PATH_MAX]; temp = realpath(exec_path, real);
temp = realpath(exec_path,real); ret = temp == NULL ? get_errno(-1) : strlen(real) ;
ret = (temp==NULL) ? get_errno(-1) : strlen(real) ; snprintf((char *)p2, arg3, "%s", real);
snprintf((char *)p2, arg3, "%s", real); } else {
} ret = get_errno(readlink(path(p), p2, arg3));
else
ret = get_errno(readlink(path(p), p2, arg3));
} }
unlock_user(p2, arg2, ret); unlock_user(p2, arg2, ret);
unlock_user(p, arg1, 0); unlock_user(p, arg1, 0);
...@@ -6287,10 +6387,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ...@@ -6287,10 +6387,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
void *p2; void *p2;
p = lock_user_string(arg2); p = lock_user_string(arg2);
p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0); p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
if (!p || !p2) if (!p || !p2) {
ret = -TARGET_EFAULT; ret = -TARGET_EFAULT;
else } else if (is_proc_myself((const char *)p, "exe")) {
char real[PATH_MAX], *temp;
temp = realpath(exec_path, real);
ret = temp == NULL ? get_errno(-1) : strlen(real) ;
snprintf((char *)p2, arg4, "%s", real);
} else {
ret = get_errno(readlinkat(arg1, path(p), p2, arg4)); ret = get_errno(readlinkat(arg1, path(p), p2, arg4));
}
unlock_user(p2, arg3, ret); unlock_user(p2, arg3, ret);
unlock_user(p, arg2, 0); unlock_user(p, arg2, 0);
} }
...@@ -8536,7 +8642,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ...@@ -8536,7 +8642,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
goto unimplemented_nowarn; goto unimplemented_nowarn;
#endif #endif
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat) #if defined(TARGET_NR_utimensat)
case TARGET_NR_utimensat: case TARGET_NR_utimensat:
{ {
struct timespec *tsp, ts[2]; struct timespec *tsp, ts[2];
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "cpu.h" #include "cpu.h"
#include "disas/disas.h" #include "disas/disas.h"
#include "tcg.h" #include "tcg.h"
#include "qemu/bitops.h"
#undef EAX #undef EAX
#undef ECX #undef ECX
...@@ -441,8 +442,11 @@ int cpu_signal_handler(int host_signum, void *pinfo, ...@@ -441,8 +442,11 @@ int cpu_signal_handler(int host_signum, void *pinfo,
#else #else
pc = uc->uc_mcontext.arm_pc; pc = uc->uc_mcontext.arm_pc;
#endif #endif
/* XXX: compute is_write */
is_write = 0; /* error_code is the FSR value, in which bit 11 is WnR (assuming a v6 or
* later processor; on v5 we will always report this as a read).
*/
is_write = extract32(uc->uc_mcontext.error_code, 11, 1);
return handle_cpu_signal(pc, (unsigned long)info->si_addr, return handle_cpu_signal(pc, (unsigned long)info->si_addr,
is_write, is_write,
&uc->uc_sigmask, puc); &uc->uc_sigmask, puc);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册