⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syscall.c

📁 qemu性能直逼VMware的仿真器QEMU 的模擬速度約為實機的 25%;約為 Bochs 的 60 倍。Plex86、User-Mode-Linux、VMware 和 Virtual PC 則比
💻 C
📖 第 1 页 / 共 5 页
字号:
        int len = tswapl(target_cmsg->cmsg_len)                   - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));        space += CMSG_SPACE(len);        if (space > msgh->msg_controllen) {            space -= CMSG_SPACE(len);            gemu_log("Host cmsg overflow\n");            break;        }        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);        cmsg->cmsg_len = CMSG_LEN(len);        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);            memcpy(data, target_data, len);        } else {            int *fd = (int *)data;            int *target_fd = (int *)target_data;            int i, numfds = len / sizeof(int);            for (i = 0; i < numfds; i++)                fd[i] = tswap32(target_fd[i]);        }        cmsg = CMSG_NXTHDR(msgh, cmsg);        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);    }    msgh->msg_controllen = space;}/* ??? Should this also swap msgh->name?  */static inline void host_to_target_cmsg(struct target_msghdr *target_msgh,                                       struct msghdr *msgh){    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);    struct target_cmsghdr *target_cmsg = TARGET_CMSG_FIRSTHDR(target_msgh);    socklen_t space = 0;    while (cmsg && target_cmsg) {        void *data = CMSG_DATA(cmsg);        void *target_data = TARGET_CMSG_DATA(target_cmsg);        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));        space += TARGET_CMSG_SPACE(len);        if (space > tswapl(target_msgh->msg_controllen)) {            space -= TARGET_CMSG_SPACE(len);            gemu_log("Target cmsg overflow\n");            break;        }        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);            memcpy(target_data, data, len);        } else {            int *fd = (int *)data;            int *target_fd = (int *)target_data;            int i, numfds = len / sizeof(int);            for (i = 0; i < numfds; i++)                target_fd[i] = tswap32(fd[i]);        }        cmsg = CMSG_NXTHDR(msgh, cmsg);        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);    }    msgh->msg_controllen = tswapl(space);}static long do_setsockopt(int sockfd, int level, int optname,                           target_ulong optval, socklen_t optlen){    int val, ret;                switch(level) {    case SOL_TCP:        /* TCP options all take an 'int' value.  */        if (optlen < sizeof(uint32_t))            return -EINVAL;                val = tget32(optval);        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));        break;    case SOL_IP:        switch(optname) {        case IP_TOS:        case IP_TTL:        case IP_HDRINCL:        case IP_ROUTER_ALERT:        case IP_RECVOPTS:        case IP_RETOPTS:        case IP_PKTINFO:        case IP_MTU_DISCOVER:        case IP_RECVERR:        case IP_RECVTOS:#ifdef IP_FREEBIND        case IP_FREEBIND:#endif        case IP_MULTICAST_TTL:        case IP_MULTICAST_LOOP:            val = 0;            if (optlen >= sizeof(uint32_t)) {                val = tget32(optval);            } else if (optlen >= 1) {                val = tget8(optval);            }            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));            break;        default:            goto unimplemented;        }        break;    case TARGET_SOL_SOCKET:        switch (optname) {            /* Options with 'int' argument.  */        case TARGET_SO_DEBUG:		optname = SO_DEBUG;		break;        case TARGET_SO_REUSEADDR:		optname = SO_REUSEADDR;		break;        case TARGET_SO_TYPE:		optname = SO_TYPE;		break;        case TARGET_SO_ERROR:		optname = SO_ERROR;		break;        case TARGET_SO_DONTROUTE:		optname = SO_DONTROUTE;		break;        case TARGET_SO_BROADCAST:		optname = SO_BROADCAST;		break;        case TARGET_SO_SNDBUF:		optname = SO_SNDBUF;		break;        case TARGET_SO_RCVBUF:		optname = SO_RCVBUF;		break;        case TARGET_SO_KEEPALIVE:		optname = SO_KEEPALIVE;		break;        case TARGET_SO_OOBINLINE:		optname = SO_OOBINLINE;		break;        case TARGET_SO_NO_CHECK:		optname = SO_NO_CHECK;		break;        case TARGET_SO_PRIORITY:		optname = SO_PRIORITY;		break;#ifdef SO_BSDCOMPAT        case TARGET_SO_BSDCOMPAT:		optname = SO_BSDCOMPAT;		break;#endif        case TARGET_SO_PASSCRED:		optname = SO_PASSCRED;		break;        case TARGET_SO_TIMESTAMP:		optname = SO_TIMESTAMP;		break;        case TARGET_SO_RCVLOWAT:		optname = SO_RCVLOWAT;		break;        case TARGET_SO_RCVTIMEO:		optname = SO_RCVTIMEO;		break;        case TARGET_SO_SNDTIMEO:		optname = SO_SNDTIMEO;		break;            break;        default:            goto unimplemented;        }	if (optlen < sizeof(uint32_t))	return -EINVAL;	val = tget32(optval);	ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));        break;    default:    unimplemented:        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);        ret = -ENOSYS;    }    return ret;}static long do_getsockopt(int sockfd, int level, int optname,                           target_ulong optval, target_ulong optlen){    int len, lv, val, ret;    switch(level) {    case TARGET_SOL_SOCKET:    	level = SOL_SOCKET;	switch (optname) {	case TARGET_SO_LINGER:	case TARGET_SO_RCVTIMEO:	case TARGET_SO_SNDTIMEO:	case TARGET_SO_PEERCRED:	case TARGET_SO_PEERNAME:	    /* These don't just return a single integer */	    goto unimplemented;        default:            goto int_case;        }        break;    case SOL_TCP:        /* TCP options all take an 'int' value.  */    int_case:        len = tget32(optlen);        if (len < 0)            return -EINVAL;        lv = sizeof(int);        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));        if (ret < 0)            return ret;        val = tswap32(val);        if (len > lv)            len = lv;        if (len == 4)            tput32(optval, val);        else            tput8(optval, val);        tput32(optlen, len);        break;    case SOL_IP:        switch(optname) {        case IP_TOS:        case IP_TTL:        case IP_HDRINCL:        case IP_ROUTER_ALERT:        case IP_RECVOPTS:        case IP_RETOPTS:        case IP_PKTINFO:        case IP_MTU_DISCOVER:        case IP_RECVERR:        case IP_RECVTOS:#ifdef IP_FREEBIND        case IP_FREEBIND:#endif        case IP_MULTICAST_TTL:        case IP_MULTICAST_LOOP:            len = tget32(optlen);            if (len < 0)                return -EINVAL;            lv = sizeof(int);            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));            if (ret < 0)                return ret;            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {                len = 1;                tput32(optlen, len);                tput8(optval, val);            } else {                if (len > sizeof(int))                    len = sizeof(int);                tput32(optlen, len);                tput32(optval, val);            }            break;        default:            goto unimplemented;        }        break;    default:    unimplemented:        gemu_log("getsockopt level=%d optname=%d not yet supported\n",                 level, optname);        ret = -ENOSYS;        break;    }    return ret;}static void lock_iovec(struct iovec *vec, target_ulong target_addr,                       int count, int copy){    struct target_iovec *target_vec;    target_ulong base;    int i;    target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1);    for(i = 0;i < count; i++) {        base = tswapl(target_vec[i].iov_base);        vec[i].iov_len = tswapl(target_vec[i].iov_len);        vec[i].iov_base = lock_user(base, vec[i].iov_len, copy);    }    unlock_user (target_vec, target_addr, 0);}static void unlock_iovec(struct iovec *vec, target_ulong target_addr,                         int count, int copy){    struct target_iovec *target_vec;    target_ulong base;    int i;    target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1);    for(i = 0;i < count; i++) {        base = tswapl(target_vec[i].iov_base);        unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);    }    unlock_user (target_vec, target_addr, 0);}static long do_socket(int domain, int type, int protocol){#if defined(TARGET_MIPS)    switch(type) {    case TARGET_SOCK_DGRAM:        type = SOCK_DGRAM;        break;    case TARGET_SOCK_STREAM:        type = SOCK_STREAM;        break;    case TARGET_SOCK_RAW:        type = SOCK_RAW;        break;    case TARGET_SOCK_RDM:        type = SOCK_RDM;        break;    case TARGET_SOCK_SEQPACKET:        type = SOCK_SEQPACKET;        break;    case TARGET_SOCK_PACKET:        type = SOCK_PACKET;        break;    }#endif    return get_errno(socket(domain, type, protocol));}static long do_bind(int sockfd, target_ulong target_addr,                    socklen_t addrlen){    void *addr = alloca(addrlen);        target_to_host_sockaddr(addr, target_addr, addrlen);    return get_errno(bind(sockfd, addr, addrlen));}static long do_connect(int sockfd, target_ulong target_addr,                    socklen_t addrlen){    void *addr = alloca(addrlen);        target_to_host_sockaddr(addr, target_addr, addrlen);    return get_errno(connect(sockfd, addr, addrlen));}static long do_sendrecvmsg(int fd, target_ulong target_msg,                           int flags, int send){    long ret;    struct target_msghdr *msgp;    struct msghdr msg;    int count;    struct iovec *vec;    target_ulong target_vec;    lock_user_struct(msgp, target_msg, 1);    if (msgp->msg_name) {        msg.msg_namelen = tswap32(msgp->msg_namelen);        msg.msg_name = alloca(msg.msg_namelen);        target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),                                msg.msg_namelen);    } else {        msg.msg_name = NULL;        msg.msg_namelen = 0;    }    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);    msg.msg_control = alloca(msg.msg_controllen);    msg.msg_flags = tswap32(msgp->msg_flags);        count = tswapl(msgp->msg_iovlen);    vec = alloca(count * sizeof(struct iovec));    target_vec = tswapl(msgp->msg_iov);    lock_iovec(vec, target_vec, count, send);    msg.msg_iovlen = count;    msg.msg_iov = vec;        if (send) {        target_to_host_cmsg(&msg, msgp);        ret = get_errno(sendmsg(fd, &msg, flags));    } else {        ret = get_errno(recvmsg(fd, &msg, flags));        if (!is_error(ret))            host_to_target_cmsg(msgp, &msg);    }    unlock_iovec(vec, target_vec, count, !send);    return ret;}static long do_accept(int fd, target_ulong target_addr,                      target_ulong target_addrlen){    socklen_t addrlen = tget32(target_addrlen);    void *addr = alloca(addrlen);    long ret;    ret = get_errno(accept(fd, addr, &addrlen));    if (!is_error(ret)) {        host_to_target_sockaddr(target_addr, addr, addrlen);        tput32(target_addrlen, addrlen);    }    return ret;}static long do_getpeername(int fd, target_ulong target_addr,                           target_ulong target_addrlen){    socklen_t addrlen = tget32(target_addrlen);    void *addr = alloca(target_addrlen);    long ret;    ret = get_errno(getpeername(fd, addr, &addrlen));    if (!is_error(ret)) {        host_to_target_sockaddr(target_addr, addr, addrlen);        tput32(target_addrlen, addrlen);    }    return ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -