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

📄 syscall.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 5 页
字号:
            socklen_t addrlen = tget32(target_addrlen);            void *addr = alloca(addrlen);            ret = get_errno(getsockname(sockfd, addr, &addrlen));            if (!is_error(ret)) {                host_to_target_sockaddr(target_addr, addr, addrlen);                tput32(target_addrlen, addrlen);            }        }        break;    case SOCKOP_getpeername:        {            int sockfd = tgetl(vptr);            target_ulong target_addr = tgetl(vptr + n);            target_ulong target_addrlen = tgetl(vptr + 2 * n);            socklen_t addrlen = tget32(target_addrlen);            void *addr = alloca(addrlen);            ret = get_errno(getpeername(sockfd, addr, &addrlen));            if (!is_error(ret)) {                host_to_target_sockaddr(target_addr, addr, addrlen);                tput32(target_addrlen, addrlen);            }        }        break;    case SOCKOP_socketpair:        {            int domain = tgetl(vptr);            int type = tgetl(vptr + n);            int protocol = tgetl(vptr + 2 * n);            target_ulong target_tab = tgetl(vptr + 3 * n);            int tab[2];            ret = get_errno(socketpair(domain, type, protocol, tab));            if (!is_error(ret)) {                tput32(target_tab, tab[0]);                tput32(target_tab + 4, tab[1]);            }        }        break;    case SOCKOP_send:        {            int sockfd = tgetl(vptr);            target_ulong msg = tgetl(vptr + n);            size_t len = tgetl(vptr + 2 * n);            int flags = tgetl(vptr + 3 * n);            void *host_msg;            host_msg = lock_user(msg, len, 1);            ret = get_errno(send(sockfd, host_msg, len, flags));            unlock_user(host_msg, msg, 0);        }        break;    case SOCKOP_recv:        {            int sockfd = tgetl(vptr);            target_ulong msg = tgetl(vptr + n);            size_t len = tgetl(vptr + 2 * n);            int flags = tgetl(vptr + 3 * n);            void *host_msg;            host_msg = lock_user(msg, len, 0);            ret = get_errno(recv(sockfd, host_msg, len, flags));            unlock_user(host_msg, msg, ret);        }        break;    case SOCKOP_sendto:        {            int sockfd = tgetl(vptr);            target_ulong msg = tgetl(vptr + n);            size_t len = tgetl(vptr + 2 * n);            int flags = tgetl(vptr + 3 * n);            target_ulong target_addr = tgetl(vptr + 4 * n);            socklen_t addrlen = tgetl(vptr + 5 * n);            void *addr = alloca(addrlen);            void *host_msg;            host_msg = lock_user(msg, len, 1);            target_to_host_sockaddr(addr, target_addr, addrlen);            ret = get_errno(sendto(sockfd, host_msg, len, flags, addr, addrlen));            unlock_user(host_msg, msg, 0);        }        break;    case SOCKOP_recvfrom:        {            int sockfd = tgetl(vptr);            target_ulong msg = tgetl(vptr + n);            size_t len = tgetl(vptr + 2 * n);            int flags = tgetl(vptr + 3 * n);            target_ulong target_addr = tgetl(vptr + 4 * n);            target_ulong target_addrlen = tgetl(vptr + 5 * n);            socklen_t addrlen = tget32(target_addrlen);            void *addr = alloca(addrlen);            void *host_msg;            host_msg = lock_user(msg, len, 0);            ret = get_errno(recvfrom(sockfd, host_msg, len, flags, addr, &addrlen));            if (!is_error(ret)) {                host_to_target_sockaddr(target_addr, addr, addrlen);                tput32(target_addrlen, addrlen);                unlock_user(host_msg, msg, len);            } else {                unlock_user(host_msg, msg, 0);            }        }        break;    case SOCKOP_shutdown:        {            int sockfd = tgetl(vptr);            int how = tgetl(vptr + n);            ret = get_errno(shutdown(sockfd, how));        }        break;    case SOCKOP_sendmsg:    case SOCKOP_recvmsg:        {            int fd;            target_ulong target_msg;            struct target_msghdr *msgp;            struct msghdr msg;            int flags, count;            struct iovec *vec;            target_ulong target_vec;            int send = (num == SOCKOP_sendmsg);            target_msg = tgetl(vptr + n);            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;            fd = tgetl(vptr);            flags = tgetl(vptr + 2 * n);            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);        }        break;    case SOCKOP_setsockopt:        {            int sockfd = tgetl(vptr);            int level = tgetl(vptr + n);            int optname = tgetl(vptr + 2 * n);            target_ulong optval = tgetl(vptr + 3 * n);            socklen_t optlen = tgetl(vptr + 4 * n);            ret = do_setsockopt(sockfd, level, optname, optval, optlen);        }        break;    case SOCKOP_getsockopt:        {            int sockfd = tgetl(vptr);            int level = tgetl(vptr + n);            int optname = tgetl(vptr + 2 * n);            target_ulong optval = tgetl(vptr + 3 * n);            target_ulong poptlen = tgetl(vptr + 4 * n);            ret = do_getsockopt(sockfd, level, optname, optval, poptlen);        }        break;    default:        gemu_log("Unsupported socketcall: %d\n", num);        ret = -ENOSYS;        break;    }    return ret;}#define N_SHM_REGIONS	32static struct shm_region {    uint32_t	start;    uint32_t	size;} shm_regions[N_SHM_REGIONS];/* ??? This only works with linear mappings.  */static long do_ipc(long call, long first, long second, long third,		   long ptr, long fifth){    int version;    long ret = 0;    unsigned long raddr;    struct shmid_ds shm_info;    int i;    version = call >> 16;    call &= 0xffff;    switch (call) {    case IPCOP_shmat:	/* SHM_* flags are the same on all linux platforms */	ret = get_errno((long) shmat(first, (void *) ptr, second));        if (is_error(ret))            break;        raddr = ret;	/* find out the length of the shared memory segment */                ret = get_errno(shmctl(first, IPC_STAT, &shm_info));        if (is_error(ret)) {            /* can't get length, bail out */            shmdt((void *) raddr);	    break;	}	page_set_flags(raddr, raddr + shm_info.shm_segsz,		       PAGE_VALID | PAGE_READ |		       ((second & SHM_RDONLY)? 0: PAGE_WRITE));	for (i = 0; i < N_SHM_REGIONS; ++i) {	    if (shm_regions[i].start == 0) {		shm_regions[i].start = raddr;		shm_regions[i].size = shm_info.shm_segsz;                break;	    }	}	if (put_user(raddr, (uint32_t *)third))            return -EFAULT;        ret = 0;	break;    case IPCOP_shmdt:	for (i = 0; i < N_SHM_REGIONS; ++i) {	    if (shm_regions[i].start == ptr) {		shm_regions[i].start = 0;		page_set_flags(ptr, shm_regions[i].size, 0);		break;	    }	}	ret = get_errno(shmdt((void *) ptr));	break;    case IPCOP_shmget:	/* IPC_* flag values are the same on all linux platforms */	ret = get_errno(shmget(first, second, third));	break;	/* IPC_* and SHM_* command values are the same on all linux platforms */    case IPCOP_shmctl:        switch(second) {        case IPC_RMID:        case SHM_LOCK:        case SHM_UNLOCK:            ret = get_errno(shmctl(first, second, NULL));            break;        default:            goto unimplemented;        }        break;    default:    unimplemented:	gemu_log("Unsupported ipc call: %ld (version %d)\n", call, version);	ret = -ENOSYS;	break;    }    return ret;}/* kernel structure types definitions */#define IFNAMSIZ        16#define STRUCT(name, list...) STRUCT_ ## name,#define STRUCT_SPECIAL(name) STRUCT_ ## name,enum {#include "syscall_types.h"};#undef STRUCT#undef STRUCT_SPECIAL#define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };#define STRUCT_SPECIAL(name)#include "syscall_types.h"#undef STRUCT#undef STRUCT_SPECIALtypedef struct IOCTLEntry {    unsigned int target_cmd;    unsigned int host_cmd;    const char *name;    int access;    const argtype arg_type[5];} IOCTLEntry;#define IOC_R 0x0001#define IOC_W 0x0002#define IOC_RW (IOC_R | IOC_W)#define MAX_STRUCT_SIZE 4096IOCTLEntry ioctl_entries[] = {#define IOCTL(cmd, access, types...) \    { TARGET_ ## cmd, cmd, #cmd, access, { types } },#include "ioctls.h"    { 0, 0, },};/* ??? Implement proper locking for ioctls.  */static long do_ioctl(long fd, long cmd, long arg){    const IOCTLEntry *ie;    const argtype *arg_type;    long ret;    uint8_t buf_temp[MAX_STRUCT_SIZE];    int target_size;    void *argptr;    ie = ioctl_entries;    for(;;) {        if (ie->target_cmd == 0) {            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", cmd);            return -ENOSYS;        }        if (ie->target_cmd == cmd)            break;        ie++;    }    arg_type = ie->arg_type;#if defined(DEBUG)    gemu_log("ioctl: cmd=0x%04lx (%s)\n", cmd, ie->name);#endif    switch(arg_type[0]) {    case TYPE_NULL:        /* no argument */        ret = get_errno(ioctl(fd, ie->host_cmd));        break;    case TYPE_PTRVOID:    case TYPE_INT:        /* int argment */        ret = get_errno(ioctl(fd, ie->host_cmd, arg));        break;    case TYPE_PTR:        arg_type++;        target_size = thunk_type_size(arg_type, 0);        switch(ie->access) {        case IOC_R:            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));            if (!is_error(ret)) {                argptr = lock_user(arg, target_size, 0);                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);                unlock_user(argptr, arg, target_size);            }            break;        case IOC_W:            argptr = lock_user(arg, target_size, 1);            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);            unlock_user(argptr, arg, 0);            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));            break;        default:        case IOC_RW:            argptr = lock_user(arg, target_size, 1);            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);            unlock_user(argptr, arg, 0);            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));            if (!is_error(ret)) {                argptr = lock_user(arg, target_size, 0);                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);                unlock_user(argptr, arg, target_size);            }            break;        }        break;    default:        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", cmd, arg_type[0]);        ret = -ENOSYS;        break;    }    return ret;}bitmask_transtbl iflag_tbl[] = {        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },        { TARGET_IXON, TARGET_IXON, IXON, IXON },        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },        { 0, 0, 0, 0 }};bitmask_transtbl oflag_tbl[] = {	{ TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },	{ TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },	{ TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },	{ TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },	{ TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },	{ TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },	{ TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },	{ TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },	{ TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },	{ TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },	{ TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },	{ TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },	{ TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },	{ TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },

⌨️ 快捷键说明

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