📄 syscall.c
字号:
{ TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 }, { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 }, { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 }, { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 }, { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 }, { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 }, { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 }, { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 }, { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 }, { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 }, { 0, 0, 0, 0 }};bitmask_transtbl cflag_tbl[] = { { TARGET_CBAUD, TARGET_B0, CBAUD, B0 }, { TARGET_CBAUD, TARGET_B50, CBAUD, B50 }, { TARGET_CBAUD, TARGET_B75, CBAUD, B75 }, { TARGET_CBAUD, TARGET_B110, CBAUD, B110 }, { TARGET_CBAUD, TARGET_B134, CBAUD, B134 }, { TARGET_CBAUD, TARGET_B150, CBAUD, B150 }, { TARGET_CBAUD, TARGET_B200, CBAUD, B200 }, { TARGET_CBAUD, TARGET_B300, CBAUD, B300 }, { TARGET_CBAUD, TARGET_B600, CBAUD, B600 }, { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 }, { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 }, { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 }, { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 }, { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 }, { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 }, { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 }, { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 }, { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 }, { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 }, { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 }, { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 }, { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 }, { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 }, { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 }, { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB }, { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD }, { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB }, { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD }, { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL }, { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL }, { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS }, { 0, 0, 0, 0 }};bitmask_transtbl lflag_tbl[] = { { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG }, { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON }, { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE }, { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO }, { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE }, { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK }, { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL }, { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH }, { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP }, { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL }, { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT }, { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE }, { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO }, { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN }, { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN }, { 0, 0, 0, 0 }};static void target_to_host_termios (void *dst, const void *src){ struct host_termios *host = dst; const struct target_termios *target = src; host->c_iflag = target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl); host->c_oflag = target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl); host->c_cflag = target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl); host->c_lflag = target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl); host->c_line = target->c_line; host->c_cc[VINTR] = target->c_cc[TARGET_VINTR]; host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT]; host->c_cc[VERASE] = target->c_cc[TARGET_VERASE]; host->c_cc[VKILL] = target->c_cc[TARGET_VKILL]; host->c_cc[VEOF] = target->c_cc[TARGET_VEOF]; host->c_cc[VTIME] = target->c_cc[TARGET_VTIME]; host->c_cc[VMIN] = target->c_cc[TARGET_VMIN]; host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC]; host->c_cc[VSTART] = target->c_cc[TARGET_VSTART]; host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP]; host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP]; host->c_cc[VEOL] = target->c_cc[TARGET_VEOL]; host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT]; host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD]; host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE]; host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT]; host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2]; } static void host_to_target_termios (void *dst, const void *src){ struct target_termios *target = dst; const struct host_termios *host = src; target->c_iflag = tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl)); target->c_oflag = tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl)); target->c_cflag = tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl)); target->c_lflag = tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl)); target->c_line = host->c_line; target->c_cc[TARGET_VINTR] = host->c_cc[VINTR]; target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT]; target->c_cc[TARGET_VERASE] = host->c_cc[VERASE]; target->c_cc[TARGET_VKILL] = host->c_cc[VKILL]; target->c_cc[TARGET_VEOF] = host->c_cc[VEOF]; target->c_cc[TARGET_VTIME] = host->c_cc[VTIME]; target->c_cc[TARGET_VMIN] = host->c_cc[VMIN]; target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC]; target->c_cc[TARGET_VSTART] = host->c_cc[VSTART]; target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP]; target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP]; target->c_cc[TARGET_VEOL] = host->c_cc[VEOL]; target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT]; target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD]; target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE]; target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT]; target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];}StructEntry struct_termios_def = { .convert = { host_to_target_termios, target_to_host_termios }, .size = { sizeof(struct target_termios), sizeof(struct host_termios) }, .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },};static bitmask_transtbl mmap_flags_tbl[] = { { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED }, { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE }, { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED }, { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS }, { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN }, { 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 }, { 0, 0, 0, 0 }};static bitmask_transtbl fcntl_flags_tbl[] = { { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, }, { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, }, { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, }, { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, }, { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, }, { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, }, { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, }, { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, }, { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, }, { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, }, { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, }, { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, }, { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },#if defined(O_DIRECT) { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },#endif { 0, 0, 0, 0 }};#if defined(TARGET_I386)/* NOTE: there is really one LDT for all the threads */uint8_t *ldt_table;static int read_ldt(target_ulong ptr, unsigned long bytecount){ int size; void *p; if (!ldt_table) return 0; size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE; if (size > bytecount) size = bytecount; p = lock_user(ptr, size, 0); /* ??? Shoudl this by byteswapped? */ memcpy(p, ldt_table, size); unlock_user(p, ptr, size); return size;}/* XXX: add locking support */static int write_ldt(CPUX86State *env, target_ulong ptr, unsigned long bytecount, int oldmode){ struct target_modify_ldt_ldt_s ldt_info; struct target_modify_ldt_ldt_s *target_ldt_info; int seg_32bit, contents, read_exec_only, limit_in_pages; int seg_not_present, useable; uint32_t *lp, entry_1, entry_2; if (bytecount != sizeof(ldt_info)) return -EINVAL; lock_user_struct(target_ldt_info, ptr, 1); ldt_info.entry_number = tswap32(target_ldt_info->entry_number); ldt_info.base_addr = tswapl(target_ldt_info->base_addr); ldt_info.limit = tswap32(target_ldt_info->limit); ldt_info.flags = tswap32(target_ldt_info->flags); unlock_user_struct(target_ldt_info, ptr, 0); if (ldt_info.entry_number >= TARGET_LDT_ENTRIES) return -EINVAL; seg_32bit = ldt_info.flags & 1; contents = (ldt_info.flags >> 1) & 3; read_exec_only = (ldt_info.flags >> 3) & 1; limit_in_pages = (ldt_info.flags >> 4) & 1; seg_not_present = (ldt_info.flags >> 5) & 1; useable = (ldt_info.flags >> 6) & 1; if (contents == 3) { if (oldmode) return -EINVAL; if (seg_not_present == 0) return -EINVAL; } /* allocate the LDT */ if (!ldt_table) { ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE); if (!ldt_table) return -ENOMEM; memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE); env->ldt.base = h2g(ldt_table); env->ldt.limit = 0xffff; } /* NOTE: same code as Linux kernel */ /* Allow LDTs to be cleared by the user. */ if (ldt_info.base_addr == 0 && ldt_info.limit == 0) { if (oldmode || (contents == 0 && read_exec_only == 1 && seg_32bit == 0 && limit_in_pages == 0 && seg_not_present == 1 && useable == 0 )) { entry_1 = 0; entry_2 = 0; goto install; } } entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) | (ldt_info.limit & 0x0ffff); entry_2 = (ldt_info.base_addr & 0xff000000) | ((ldt_info.base_addr & 0x00ff0000) >> 16) | (ldt_info.limit & 0xf0000) | ((read_exec_only ^ 1) << 9) | (contents << 10) | ((seg_not_present ^ 1) << 15) | (seg_32bit << 22) | (limit_in_pages << 23) | 0x7000; if (!oldmode) entry_2 |= (useable << 20); /* Install the new entry ... */install: lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3)); lp[0] = tswap32(entry_1); lp[1] = tswap32(entry_2); return 0;}/* specific and weird i386 syscalls */int do_modify_ldt(CPUX86State *env, int func, target_ulong ptr, unsigned long bytecount){ int ret = -ENOSYS; switch (func) { case 0: ret = read_ldt(ptr, bytecount); break; case 1: ret = write_ldt(env, ptr, bytecount, 1); break; case 0x11: ret = write_ldt(env, ptr, bytecount, 0); break; } return ret;}#endif /* defined(TARGET_I386) *//* this stack is the equivalent of the kernel stack associated with a thread/process */#define NEW_STACK_SIZE 8192static int clone_func(void *arg){ CPUState *env = arg; cpu_loop(env); /* never exits */ return 0;}int do_fork(CPUState *env, unsigned int flags, unsigned long newsp){ int ret; TaskState *ts; uint8_t *new_stack; CPUState *new_env; if (flags & CLONE_VM) { ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); memset(ts, 0, sizeof(TaskState)); new_stack = ts->stack; ts->used = 1; /* add in task state list */ ts->next = first_task_state; first_task_state = ts; /* we create a new CPU instance. */ new_env = cpu_init(); memcpy(new_env, env, sizeof(CPUState));#if defined(TARGET_I386) if (!newsp) newsp = env->regs[R_ESP]; new_env->regs[R_ESP] = newsp; new_env->regs[R_EAX] = 0;#elif defined(TARGET_ARM) if (!newsp) newsp = env->regs[13]; new_env->regs[13] = newsp; new_env->regs[0] = 0;#elif defined(TARGET_SPARC) printf ("HELPME: %s:%d\n", __FILE__, __LINE__);#elif defined(TARGET_MIPS) printf ("HELPME: %s:%d\n", __FILE__, __LINE__);#elif defined(TARGET_PPC) if (!newsp) newsp = env->gpr[1]; new_env->gpr[1] = newsp; { int i; for (i = 7; i < 32; i++) new_env->gpr[i] = 0; }#elif defined(TARGET_SH4) if (!newsp) newsp = env->gregs[15]; new_env->gregs[15] = newsp; /* XXXXX */#else#error unsupported target CPU#endif new_env->opaque = ts;#ifdef __ia64__ ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);#else ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);#endif } else { /* if no CLONE_VM, we consider it is a fork */ if ((flags & ~CSIGNAL) != 0) return -EINVAL; ret = fork(); } return ret;}static long do_fcntl(int fd, int cmd, target_ulong arg){ struct flock fl; struct target_flock *target_fl; long ret; switch(cmd) { case TARGET_F_GETLK: ret = fcntl(fd, cmd, &fl); if (ret == 0) { lock_user_struct(target_fl, arg, 0); target_fl->l_type = tswap16(fl.l_type); target_fl->l_whence = tswap16(fl.l_whence); target_fl->l_start = tswapl(fl.l_start); target_fl->l_len = tswapl(fl.l_len); target_fl->l_pid = tswapl(fl.l_pid); unlock_user_struct(target_fl, arg, 1); } break; case TARGET_F_SETLK: case TARGET_F_SETLKW: lock_user_struct(target_fl, arg, 1); fl.l_type = tswap16(target_fl->l_type); fl.l_whence = tswap16(target_fl->l_whence); fl.l_start = tswapl(target_fl->l_start); fl.l_len = tswapl(target_fl->l_len); fl.l_pid = tswapl(target_fl->l_pid); unlock_user_struct(target_fl, arg, 0); ret = fcntl(fd, cmd, &fl); break; case TARGET_F_GETLK64: case TARGET_F_SETLK64: case TARGET_F_SETLKW64: ret = -1; errno = EINVAL; break; case F_GETFL: ret = fcntl(fd, cmd, arg); ret = host_to_target_bitmask(ret, fcntl_flags_tbl); break; case F_SETFL: ret = fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)); break; default:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -