Merge remote-tracking branch 'remotes/riku/linux-user-for-upstream' into staging
* remotes/riku/linux-user-for-upstream:
  linux-user: support the SIOCGIFINDEX ioctl
  linux-user: support the KDSIGACCEPT ioctl
  linux-user: allow NULL tv argument for settimeofday
  linux-user: respect timezone for settimeofday
  linux-user: fix struct target_epoll_event layout for MIPS
  linux-user: support strace of epoll_create1
  linux-user: allow NULL arguments to mount
  linux-user: support SO_PASSSEC setsockopt option
  linux-user: support SO_{SND, RCV}BUFFORCE setsockopt options
  linux-user: support SO_ACCEPTCONN getsockopt option
  linux-user: translate the result of getsockopt SO_TYPE
  linux-user: added fake open() for /proc/self/cmdline
  Add support for MAP_NORESERVE mmap flag.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
			
			
This commit is contained in:
		
						commit
						4f9c5be919
					
				| 
						 | 
				
			
			@ -64,6 +64,7 @@
 | 
			
		|||
     IOCTL(KDSKBLED, 0, TYPE_INT)
 | 
			
		||||
     IOCTL(KDGETLED, 0, TYPE_INT)
 | 
			
		||||
     IOCTL(KDSETLED, 0, TYPE_INT)
 | 
			
		||||
     IOCTL_SPECIAL(KDSIGACCEPT, 0, do_ioctl_kdsigaccept, TYPE_INT)
 | 
			
		||||
 | 
			
		||||
     IOCTL(BLKROSET, IOC_W, MK_PTR(TYPE_INT))
 | 
			
		||||
     IOCTL(BLKROGET, IOC_R, MK_PTR(TYPE_INT))
 | 
			
		||||
| 
						 | 
				
			
			@ -117,6 +118,7 @@
 | 
			
		|||
  IOCTL(SIOCSIFMEM, IOC_W, MK_PTR(MK_STRUCT(STRUCT_ptr_ifreq)))
 | 
			
		||||
  IOCTL(SIOCADDMULTI, 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(SIOCSIFLINK, 0, TYPE_NULL)
 | 
			
		||||
  IOCTL_SPECIAL(SIOCGIFCONF, IOC_W | IOC_R, do_ioctl_ifconf,
 | 
			
		||||
                MK_PTR(MK_STRUCT(STRUCT_ifconf)))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,6 +63,7 @@
 | 
			
		|||
    #define TARGET_SO_PEERSEC              30
 | 
			
		||||
    #define TARGET_SO_SNDBUFFORCE          31
 | 
			
		||||
    #define TARGET_SO_RCVBUFFORCE          33
 | 
			
		||||
    #define TARGET_SO_PASSSEC              34
 | 
			
		||||
 | 
			
		||||
    /** sock_type - Socket types
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			@ -242,6 +243,10 @@
 | 
			
		|||
 | 
			
		||||
    #define TARGET_SOCK_MAX (TARGET_SOCK_PACKET + 1)
 | 
			
		||||
    #define TARGET_SOCK_TYPE_MASK    0xf  /* Covers up to TARGET_SOCK_MAX-1. */
 | 
			
		||||
 | 
			
		||||
    #define TARGET_SO_PASSSEC        31
 | 
			
		||||
#else
 | 
			
		||||
    #define TARGET_SO_PASSSEC        34
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* For setsockopt(2) */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -114,6 +114,9 @@
 | 
			
		|||
#ifdef TARGET_NR_epoll_create
 | 
			
		||||
{ TARGET_NR_epoll_create, "epoll_create" , NULL, NULL, NULL },
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef TARGET_NR_epoll_create1
 | 
			
		||||
{ TARGET_NR_epoll_create1, "epoll_create1" , NULL, NULL, NULL },
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef TARGET_NR_epoll_ctl
 | 
			
		||||
{ TARGET_NR_epoll_ctl, "epoll_ctl" , NULL, NULL, NULL },
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -592,6 +592,37 @@ char *target_strerror(int err)
 | 
			
		|||
    return strerror(target_to_host_errno(err));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int host_to_target_sock_type(int host_type)
 | 
			
		||||
{
 | 
			
		||||
    int target_type;
 | 
			
		||||
 | 
			
		||||
    switch (host_type & 0xf /* SOCK_TYPE_MASK */) {
 | 
			
		||||
    case SOCK_DGRAM:
 | 
			
		||||
        target_type = TARGET_SOCK_DGRAM;
 | 
			
		||||
        break;
 | 
			
		||||
    case SOCK_STREAM:
 | 
			
		||||
        target_type = TARGET_SOCK_STREAM;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        target_type = host_type & 0xf /* SOCK_TYPE_MASK */;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if defined(SOCK_CLOEXEC)
 | 
			
		||||
    if (host_type & SOCK_CLOEXEC) {
 | 
			
		||||
        target_type |= TARGET_SOCK_CLOEXEC;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(SOCK_NONBLOCK)
 | 
			
		||||
    if (host_type & SOCK_NONBLOCK) {
 | 
			
		||||
        target_type |= TARGET_SOCK_NONBLOCK;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return target_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static abi_ulong target_brk;
 | 
			
		||||
static abi_ulong target_original_brk;
 | 
			
		||||
static abi_ulong brk_page;
 | 
			
		||||
| 
						 | 
				
			
			@ -904,6 +935,23 @@ static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
 | 
			
		|||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline abi_long copy_from_user_timezone(struct timezone *tz,
 | 
			
		||||
                                               abi_ulong target_tz_addr)
 | 
			
		||||
{
 | 
			
		||||
    struct target_timezone *target_tz;
 | 
			
		||||
 | 
			
		||||
    if (!lock_user_struct(VERIFY_READ, target_tz, target_tz_addr, 1)) {
 | 
			
		||||
        return -TARGET_EFAULT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    __get_user(tz->tz_minuteswest, &target_tz->tz_minuteswest);
 | 
			
		||||
    __get_user(tz->tz_dsttime, &target_tz->tz_dsttime);
 | 
			
		||||
 | 
			
		||||
    unlock_user_struct(target_tz, target_tz_addr, 0);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
 | 
			
		||||
#include <mqueue.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1471,9 +1519,15 @@ set_timeout:
 | 
			
		|||
        case TARGET_SO_SNDBUF:
 | 
			
		||||
		optname = SO_SNDBUF;
 | 
			
		||||
		break;
 | 
			
		||||
        case TARGET_SO_SNDBUFFORCE:
 | 
			
		||||
                optname = SO_SNDBUFFORCE;
 | 
			
		||||
                break;
 | 
			
		||||
        case TARGET_SO_RCVBUF:
 | 
			
		||||
		optname = SO_RCVBUF;
 | 
			
		||||
		break;
 | 
			
		||||
        case TARGET_SO_RCVBUFFORCE:
 | 
			
		||||
                optname = SO_RCVBUFFORCE;
 | 
			
		||||
                break;
 | 
			
		||||
        case TARGET_SO_KEEPALIVE:
 | 
			
		||||
		optname = SO_KEEPALIVE;
 | 
			
		||||
		break;
 | 
			
		||||
| 
						 | 
				
			
			@ -1494,6 +1548,9 @@ set_timeout:
 | 
			
		|||
        case TARGET_SO_PASSCRED:
 | 
			
		||||
		optname = SO_PASSCRED;
 | 
			
		||||
		break;
 | 
			
		||||
        case TARGET_SO_PASSSEC:
 | 
			
		||||
                optname = SO_PASSSEC;
 | 
			
		||||
                break;
 | 
			
		||||
        case TARGET_SO_TIMESTAMP:
 | 
			
		||||
		optname = SO_TIMESTAMP;
 | 
			
		||||
		break;
 | 
			
		||||
| 
						 | 
				
			
			@ -1621,6 +1678,9 @@ static abi_long do_getsockopt(int sockfd, int level, int optname,
 | 
			
		|||
        case TARGET_SO_RCVLOWAT:
 | 
			
		||||
            optname = SO_RCVLOWAT;
 | 
			
		||||
            goto int_case;
 | 
			
		||||
        case TARGET_SO_ACCEPTCONN:
 | 
			
		||||
            optname = SO_ACCEPTCONN;
 | 
			
		||||
            goto int_case;
 | 
			
		||||
        default:
 | 
			
		||||
            goto int_case;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -1636,6 +1696,9 @@ static abi_long do_getsockopt(int sockfd, int level, int optname,
 | 
			
		|||
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
 | 
			
		||||
        if (ret < 0)
 | 
			
		||||
            return ret;
 | 
			
		||||
        if (optname == SO_TYPE) {
 | 
			
		||||
            val = host_to_target_sock_type(val);
 | 
			
		||||
        }
 | 
			
		||||
        if (len > lv)
 | 
			
		||||
            len = lv;
 | 
			
		||||
        if (len == 4) {
 | 
			
		||||
| 
						 | 
				
			
			@ -3626,6 +3689,13 @@ static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
 | 
			
		|||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static abi_long do_ioctl_kdsigaccept(const IOCTLEntry *ie, uint8_t *buf_temp,
 | 
			
		||||
                                     int fd, abi_long cmd, abi_long arg)
 | 
			
		||||
{
 | 
			
		||||
    int sig = target_to_host_signal(arg);
 | 
			
		||||
    return get_errno(ioctl(fd, ie->host_cmd, sig));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static IOCTLEntry ioctl_entries[] = {
 | 
			
		||||
#define IOCTL(cmd, access, ...) \
 | 
			
		||||
    { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },
 | 
			
		||||
| 
						 | 
				
			
			@ -3908,6 +3978,8 @@ static bitmask_transtbl mmap_flags_tbl[] = {
 | 
			
		|||
	{ TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
 | 
			
		||||
	{ TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
 | 
			
		||||
	{ TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
 | 
			
		||||
        { TARGET_MAP_NORESERVE, TARGET_MAP_NORESERVE, MAP_NORESERVE,
 | 
			
		||||
          MAP_NORESERVE },
 | 
			
		||||
	{ 0, 0, 0, 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4947,6 +5019,51 @@ int host_to_target_waitstatus(int status)
 | 
			
		|||
    return status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int open_self_cmdline(void *cpu_env, int fd)
 | 
			
		||||
{
 | 
			
		||||
    int fd_orig = -1;
 | 
			
		||||
    bool word_skipped = false;
 | 
			
		||||
 | 
			
		||||
    fd_orig = open("/proc/self/cmdline", O_RDONLY);
 | 
			
		||||
    if (fd_orig < 0) {
 | 
			
		||||
        return fd_orig;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while (true) {
 | 
			
		||||
        ssize_t nb_read;
 | 
			
		||||
        char buf[128];
 | 
			
		||||
        char *cp_buf = buf;
 | 
			
		||||
 | 
			
		||||
        nb_read = read(fd_orig, buf, sizeof(buf));
 | 
			
		||||
        if (nb_read < 0) {
 | 
			
		||||
            fd_orig = close(fd_orig);
 | 
			
		||||
            return -1;
 | 
			
		||||
        } else if (nb_read == 0) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!word_skipped) {
 | 
			
		||||
            /* Skip the first string, which is the path to qemu-*-static
 | 
			
		||||
               instead of the actual command. */
 | 
			
		||||
            cp_buf = memchr(buf, 0, sizeof(buf));
 | 
			
		||||
            if (cp_buf) {
 | 
			
		||||
                /* Null byte found, skip one string */
 | 
			
		||||
                cp_buf++;
 | 
			
		||||
                nb_read -= cp_buf - buf;
 | 
			
		||||
                word_skipped = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (word_skipped) {
 | 
			
		||||
            if (write(fd, cp_buf, nb_read) != nb_read) {
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return close(fd_orig);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int open_self_maps(void *cpu_env, int fd)
 | 
			
		||||
{
 | 
			
		||||
#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
 | 
			
		||||
| 
						 | 
				
			
			@ -5148,6 +5265,7 @@ static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
 | 
			
		|||
        { "maps", open_self_maps, is_proc_myself },
 | 
			
		||||
        { "stat", open_self_stat, is_proc_myself },
 | 
			
		||||
        { "auxv", open_self_auxv, is_proc_myself },
 | 
			
		||||
        { "cmdline", open_self_cmdline, is_proc_myself },
 | 
			
		||||
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
 | 
			
		||||
        { "/proc/net/route", open_net_route, is_proc },
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -5520,29 +5638,60 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 | 
			
		|||
        break;
 | 
			
		||||
#endif
 | 
			
		||||
    case TARGET_NR_mount:
 | 
			
		||||
		{
 | 
			
		||||
			/* need to look at the data field */
 | 
			
		||||
			void *p2, *p3;
 | 
			
		||||
			p = lock_user_string(arg1);
 | 
			
		||||
			p2 = lock_user_string(arg2);
 | 
			
		||||
			p3 = lock_user_string(arg3);
 | 
			
		||||
                        if (!p || !p2 || !p3)
 | 
			
		||||
                            ret = -TARGET_EFAULT;
 | 
			
		||||
                        else {
 | 
			
		||||
                            /* FIXME - arg5 should be locked, but it isn't clear how to
 | 
			
		||||
                             * do that since it's not guaranteed to be a NULL-terminated
 | 
			
		||||
                             * string.
 | 
			
		||||
                             */
 | 
			
		||||
                            if ( ! arg5 )
 | 
			
		||||
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, NULL));
 | 
			
		||||
                            else
 | 
			
		||||
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
 | 
			
		||||
                        }
 | 
			
		||||
        {
 | 
			
		||||
            /* need to look at the data field */
 | 
			
		||||
            void *p2, *p3;
 | 
			
		||||
 | 
			
		||||
            if (arg1) {
 | 
			
		||||
                p = lock_user_string(arg1);
 | 
			
		||||
                if (!p) {
 | 
			
		||||
                    goto efault;
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                p = NULL;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            p2 = lock_user_string(arg2);
 | 
			
		||||
            if (!p2) {
 | 
			
		||||
                if (arg1) {
 | 
			
		||||
                    unlock_user(p, arg1, 0);
 | 
			
		||||
                }
 | 
			
		||||
                goto efault;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (arg3) {
 | 
			
		||||
                p3 = lock_user_string(arg3);
 | 
			
		||||
                if (!p3) {
 | 
			
		||||
                    if (arg1) {
 | 
			
		||||
                        unlock_user(p, arg1, 0);
 | 
			
		||||
                        unlock_user(p2, arg2, 0);
 | 
			
		||||
                        unlock_user(p3, arg3, 0);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
                    }
 | 
			
		||||
                    unlock_user(p2, arg2, 0);
 | 
			
		||||
                    goto efault;
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                p3 = NULL;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* FIXME - arg5 should be locked, but it isn't clear how to
 | 
			
		||||
             * do that since it's not guaranteed to be a NULL-terminated
 | 
			
		||||
             * string.
 | 
			
		||||
             */
 | 
			
		||||
            if (!arg5) {
 | 
			
		||||
                ret = mount(p, p2, p3, (unsigned long)arg4, NULL);
 | 
			
		||||
            } else {
 | 
			
		||||
                ret = mount(p, p2, p3, (unsigned long)arg4, g2h(arg5));
 | 
			
		||||
            }
 | 
			
		||||
            ret = get_errno(ret);
 | 
			
		||||
 | 
			
		||||
            if (arg1) {
 | 
			
		||||
                unlock_user(p, arg1, 0);
 | 
			
		||||
            }
 | 
			
		||||
            unlock_user(p2, arg2, 0);
 | 
			
		||||
            if (arg3) {
 | 
			
		||||
                unlock_user(p3, arg3, 0);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
#ifdef TARGET_NR_umount
 | 
			
		||||
    case TARGET_NR_umount:
 | 
			
		||||
        if (!(p = lock_user_string(arg1)))
 | 
			
		||||
| 
						 | 
				
			
			@ -6259,10 +6408,24 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 | 
			
		|||
        break;
 | 
			
		||||
    case TARGET_NR_settimeofday:
 | 
			
		||||
        {
 | 
			
		||||
            struct timeval tv;
 | 
			
		||||
            if (copy_from_user_timeval(&tv, arg1))
 | 
			
		||||
                goto efault;
 | 
			
		||||
            ret = get_errno(settimeofday(&tv, NULL));
 | 
			
		||||
            struct timeval tv, *ptv = NULL;
 | 
			
		||||
            struct timezone tz, *ptz = NULL;
 | 
			
		||||
 | 
			
		||||
            if (arg1) {
 | 
			
		||||
                if (copy_from_user_timeval(&tv, arg1)) {
 | 
			
		||||
                    goto efault;
 | 
			
		||||
                }
 | 
			
		||||
                ptv = &tv;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (arg2) {
 | 
			
		||||
                if (copy_from_user_timezone(&tz, arg2)) {
 | 
			
		||||
                    goto efault;
 | 
			
		||||
                }
 | 
			
		||||
                ptz = &tz;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            ret = get_errno(settimeofday(ptv, ptz));
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
#if defined(TARGET_NR_select)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -165,6 +165,11 @@ struct target_timespec {
 | 
			
		|||
    abi_long tv_nsec;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct target_timezone {
 | 
			
		||||
    abi_int tz_minuteswest;
 | 
			
		||||
    abi_int tz_dsttime;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct target_itimerval {
 | 
			
		||||
    struct target_timeval it_interval;
 | 
			
		||||
    struct target_timeval it_value;
 | 
			
		||||
| 
						 | 
				
			
			@ -826,6 +831,7 @@ struct target_pollfd {
 | 
			
		|||
#define TARGET_KDSKBLED        0x4B65	/* set led flags (not lights) */
 | 
			
		||||
#define TARGET_KDGETLED        0x4B31	/* return current led state */
 | 
			
		||||
#define TARGET_KDSETLED        0x4B32	/* set led state [lights, not flags] */
 | 
			
		||||
#define TARGET_KDSIGACCEPT     0x4B4E
 | 
			
		||||
 | 
			
		||||
#define TARGET_SIOCATMARK      0x8905
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -859,6 +865,7 @@ struct target_pollfd {
 | 
			
		|||
#define TARGET_SIOCSIFSLAVE    0x8930
 | 
			
		||||
#define TARGET_SIOCADDMULTI    0x8931          /* Multicast address lists      */
 | 
			
		||||
#define TARGET_SIOCDELMULTI    0x8932
 | 
			
		||||
#define TARGET_SIOCGIFINDEX    0x8933
 | 
			
		||||
 | 
			
		||||
/* Bridging control calls */
 | 
			
		||||
#define TARGET_SIOCGIFBR       0x8940          /* Bridging support             */
 | 
			
		||||
| 
						 | 
				
			
			@ -2528,7 +2535,7 @@ typedef union target_epoll_data {
 | 
			
		|||
 | 
			
		||||
struct target_epoll_event {
 | 
			
		||||
    uint32_t events;
 | 
			
		||||
#ifdef TARGET_ARM
 | 
			
		||||
#if defined(TARGET_ARM) || defined(TARGET_MIPS) || defined(TARGET_MIPS64)
 | 
			
		||||
    uint32_t __pad;
 | 
			
		||||
#endif
 | 
			
		||||
    target_epoll_data_t data;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue