📄 syscall.c.svn-base
字号:
new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1); mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0)); if (is_error(mapped_addr)) { return mapped_addr; } else { target_brk = new_brk; return target_brk; }}static inline abi_long copy_from_user_fdset(fd_set *fds, abi_ulong target_fds_addr, int n){ int i, nw, j, k; abi_ulong b, *target_fds; nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS; if (!(target_fds = lock_user(VERIFY_READ, target_fds_addr, sizeof(abi_ulong) * nw, 1))) return -TARGET_EFAULT; FD_ZERO(fds); k = 0; for (i = 0; i < nw; i++) { /* grab the abi_ulong */ __get_user(b, &target_fds[i]); for (j = 0; j < TARGET_ABI_BITS; j++) { /* check the bit inside the abi_ulong */ if ((b >> j) & 1) FD_SET(k, fds); k++; } } unlock_user(target_fds, target_fds_addr, 0); return 0;}static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr, const fd_set *fds, int n){ int i, nw, j, k; abi_long v; abi_ulong *target_fds; nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS; if (!(target_fds = lock_user(VERIFY_WRITE, target_fds_addr, sizeof(abi_ulong) * nw, 0))) return -TARGET_EFAULT; k = 0; for (i = 0; i < nw; i++) { v = 0; for (j = 0; j < TARGET_ABI_BITS; j++) { v |= ((FD_ISSET(k, fds) != 0) << j); k++; } __put_user(v, &target_fds[i]); } unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw); return 0;}#if defined(__alpha__)#define HOST_HZ 1024#else#define HOST_HZ 100#endifstatic inline abi_long host_to_target_clock_t(long ticks){#if HOST_HZ == TARGET_HZ return ticks;#else return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;#endif}static inline abi_long host_to_target_rusage(abi_ulong target_addr, const struct rusage *rusage){ struct target_rusage *target_rusage; if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0)) return -TARGET_EFAULT; target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec); target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec); target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec); target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec); target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss); target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss); target_rusage->ru_idrss = tswapl(rusage->ru_idrss); target_rusage->ru_isrss = tswapl(rusage->ru_isrss); target_rusage->ru_minflt = tswapl(rusage->ru_minflt); target_rusage->ru_majflt = tswapl(rusage->ru_majflt); target_rusage->ru_nswap = tswapl(rusage->ru_nswap); target_rusage->ru_inblock = tswapl(rusage->ru_inblock); target_rusage->ru_oublock = tswapl(rusage->ru_oublock); target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd); target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv); target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals); target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw); target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw); unlock_user_struct(target_rusage, target_addr, 1); return 0;}static inline abi_long copy_from_user_timeval(struct timeval *tv, abi_ulong target_tv_addr){ struct target_timeval *target_tv; if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1)) return -TARGET_EFAULT; __get_user(tv->tv_sec, &target_tv->tv_sec); __get_user(tv->tv_usec, &target_tv->tv_usec); unlock_user_struct(target_tv, target_tv_addr, 0); return 0;}static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr, const struct timeval *tv){ struct target_timeval *target_tv; if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0)) return -TARGET_EFAULT; __put_user(tv->tv_sec, &target_tv->tv_sec); __put_user(tv->tv_usec, &target_tv->tv_usec); unlock_user_struct(target_tv, target_tv_addr, 1); return 0;}/* do_select() must return target values and target errnos. */static abi_long do_select(int n, abi_ulong rfd_addr, abi_ulong wfd_addr, abi_ulong efd_addr, abi_ulong target_tv_addr){ fd_set rfds, wfds, efds; fd_set *rfds_ptr, *wfds_ptr, *efds_ptr; struct timeval tv, *tv_ptr; abi_long ret; if (rfd_addr) { if (copy_from_user_fdset(&rfds, rfd_addr, n)) return -TARGET_EFAULT; rfds_ptr = &rfds; } else { rfds_ptr = NULL; } if (wfd_addr) { if (copy_from_user_fdset(&wfds, wfd_addr, n)) return -TARGET_EFAULT; wfds_ptr = &wfds; } else { wfds_ptr = NULL; } if (efd_addr) { if (copy_from_user_fdset(&efds, efd_addr, n)) return -TARGET_EFAULT; efds_ptr = &efds; } else { efds_ptr = NULL; } if (target_tv_addr) { if (copy_from_user_timeval(&tv, target_tv_addr)) return -TARGET_EFAULT; tv_ptr = &tv; } else { tv_ptr = NULL; } ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr)); if (!is_error(ret)) { if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n)) return -TARGET_EFAULT; if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n)) return -TARGET_EFAULT; if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n)) return -TARGET_EFAULT; if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv)) return -TARGET_EFAULT; } return ret;}static inline abi_long target_to_host_sockaddr(struct sockaddr *addr, abi_ulong target_addr, socklen_t len){ struct target_sockaddr *target_saddr; target_saddr = lock_user(VERIFY_READ, target_addr, len, 1); if (!target_saddr) return -TARGET_EFAULT; memcpy(addr, target_saddr, len); addr->sa_family = tswap16(target_saddr->sa_family); unlock_user(target_saddr, target_addr, 0); return 0;}static inline abi_long host_to_target_sockaddr(abi_ulong target_addr, struct sockaddr *addr, socklen_t len){ struct target_sockaddr *target_saddr; target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0); if (!target_saddr) return -TARGET_EFAULT; memcpy(target_saddr, addr, len); target_saddr->sa_family = tswap16(addr->sa_family); unlock_user(target_saddr, target_addr, len); return 0;}/* ??? Should this also swap msgh->name? */static inline abi_long target_to_host_cmsg(struct msghdr *msgh, struct target_msghdr *target_msgh){ struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh); abi_long msg_controllen; abi_ulong target_cmsg_addr; struct target_cmsghdr *target_cmsg; socklen_t space = 0; msg_controllen = tswapl(target_msgh->msg_controllen); if (msg_controllen < sizeof (struct target_cmsghdr)) goto the_end; target_cmsg_addr = tswapl(target_msgh->msg_control); target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1); if (!target_cmsg) return -TARGET_EFAULT; while (cmsg && target_cmsg) { void *data = CMSG_DATA(cmsg); void *target_data = TARGET_CMSG_DATA(target_cmsg); 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); } unlock_user(target_cmsg, target_cmsg_addr, 0); the_end: msgh->msg_controllen = space; return 0;}/* ??? Should this also swap msgh->name? */static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh, struct msghdr *msgh){ struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh); abi_long msg_controllen; abi_ulong target_cmsg_addr; struct target_cmsghdr *target_cmsg; socklen_t space = 0; msg_controllen = tswapl(target_msgh->msg_controllen); if (msg_controllen < sizeof (struct target_cmsghdr)) goto the_end; target_cmsg_addr = tswapl(target_msgh->msg_control); target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0); if (!target_cmsg) return -TARGET_EFAULT; 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 > 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); } unlock_user(target_cmsg, target_cmsg_addr, space); the_end: target_msgh->msg_controllen = tswapl(space); return 0;}/* do_setsockopt() Must return target values and target errnos. */static abi_long do_setsockopt(int sockfd, int level, int optname, abi_ulong optval_addr, socklen_t optlen){ abi_long ret; int val; switch(level) { case SOL_TCP: /* TCP options all take an 'int' value. */ if (optlen < sizeof(uint32_t)) return -TARGET_EINVAL; if (get_user_u32(val, optval_addr)) return -TARGET_EFAULT; 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)) { if (get_user_u32(val, optval_addr)) return -TARGET_EFAULT; } else if (optlen >= 1) { if (get_user_u8(val, optval_addr)) return -TARGET_EFAULT; } 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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -