?? syscall.c
字號:
}long do_fstat(uint32_t arg1, struct stat * arg2){ long ret; DPRINTF("fstat(0x%x, %p)\n", arg1, arg2); ret = get_errno(fstat(arg1, arg2)); if(!is_error(ret)) byteswap_stat(arg2); return ret;}long do_lstat(char * arg1, struct stat * arg2){ long ret; /* XXX: don't let the %s stay in there */ DPRINTF("lstat(%s, %p)\n", (const char *)arg1, arg2); ret = get_errno(lstat(arg1, arg2)); if(!is_error(ret)) byteswap_stat(arg2); return ret;}long do_getdirentries(uint32_t arg1, void* arg2, uint32_t arg3, void* arg4){ long ret; DPRINTF("getdirentries(0x%x, %p, 0x%x, %p)\n", arg1, arg2, arg3, arg4); if(arg4) tswap32s((uint32_t *)arg4); ret = get_errno(getdirentries(arg1, arg2, arg3, arg4)); if(arg4) tswap32s((uint32_t *)arg4); if(!is_error(ret)) byteswap_dirents(arg2, ret); return ret;}long do_lseek(void *cpu_env, int num){ long ret; int i = 0; uint32_t arg1 = get_int_arg(&i, cpu_env); uint64_t offset = get_int64_arg(&i, cpu_env); uint32_t arg3 = get_int_arg(&i, cpu_env); uint64_t r = lseek(arg1, offset, arg3);#ifdef TARGET_I386 /* lowest word in eax, highest in edx */ ret = r & 0xffffffff; /* will be set to eax after do_unix_syscall exit */ ((CPUX86State *)cpu_env)->regs[R_EDX] = (uint32_t)((r >> 32) & 0xffffffff) ;#elif defined TARGET_PPC ret = r & 0xffffffff; /* will be set to r3 after do_unix_syscall exit */ ((CPUPPCState *)cpu_env)->gpr[4] = (uint32_t)((r >> 32) & 0xffffffff) ;#else qerror("64 bit ret value on your arch?");#endif return get_errno(ret);}void no_swap(void * oldp, int size){}void sysctl_tswap32s(void * oldp, int size){ tswap32s(oldp);}void bswap_oid(uint32_t * oldp, int size){ int count = size / sizeof(int); int i = 0; do { tswap32s(oldp + i); } while (++i < count);}void sysctl_usrstack(uint32_t * oldp, int size){ DPRINTF("sysctl_usrstack: 0x%x\n", *oldp); tswap32s(oldp);}void sysctl_ncpu(uint32_t * ncpu, int size){ *ncpu = 0x1; DPRINTF("sysctl_ncpu: 0x%x\n", *ncpu); tswap32s(ncpu);}void sysctl_exec(char * exec, int size){ DPRINTF("sysctl_exec: %s\n", exec);}void sysctl_translate(char * exec, int size){ DPRINTF("sysctl_translate: %s\n", exec);}struct sysctl_dir { int num; const char * name; void (*swap_func)(void *, int); struct sysctl_dir *childs;};#define ENTRYD(num, name, childs) { num, name, NULL, childs }#define ENTRYE(num, name, func) { num, name, (void (*)(void *, int))func, NULL }struct sysctl_dir sysctls_unspec[] = { ENTRYE(3, "oip", bswap_oid), { 0, NULL, NULL, NULL }};struct sysctl_dir sysctls_kern[] = { ENTRYE(KERN_TRANSLATE, "translate", sysctl_translate), /* 44 */ ENTRYE(KERN_EXEC, "exec", sysctl_exec), /* 45 */ ENTRYE(KERN_USRSTACK32, "KERN_USRSTACK32", sysctl_usrstack), /* 35 */ ENTRYE(KERN_SHREG_PRIVATIZABLE, "KERN_SHREG_PRIVATIZABLE", sysctl_tswap32s), /* 54 */ { 0, NULL, NULL, NULL }};struct sysctl_dir sysctls_hw[] = { ENTRYE(HW_NCPU, "ncpud", sysctl_tswap32s), ENTRYE(104, "104", no_swap), ENTRYE(105, "105", no_swap), { 0, NULL, NULL, NULL }};struct sysctl_dir sysctls[] = { ENTRYD(CTL_UNSPEC, "unspec", sysctls_unspec), ENTRYD(CTL_KERN, "kern", sysctls_kern), ENTRYD(CTL_HW, "hw", sysctls_hw ), { 0, NULL, NULL, NULL }};#undef ENTRYE#undef ENTRYDstatic inline struct sysctl_dir * get_sysctl_entry_for_mib(int mib, struct sysctl_dir * sysctl_elmt){ if(!sysctl_elmt) return NULL; for(; sysctl_elmt->name != NULL ; sysctl_elmt++) { if(sysctl_elmt->num == mib) return sysctl_elmt; } return NULL;}static inline long bswap_syctl(int * mib, int count, void *buf, int size){ int i; struct sysctl_dir * sysctl = sysctls; struct sysctl_dir * ret = NULL; for(i = 0; i < count; i++) { if(!(ret = sysctl = get_sysctl_entry_for_mib(mib[i], sysctl))) { gemu_log("bswap_syctl: can't find mib %d\n", mib[i]); return -ENOTDIR; } if(!(sysctl = sysctl->childs)) break; } if(ret->childs) qerror("we shouldn't have a directory element\n"); ret->swap_func(buf, size); return 0;}static inline void print_syctl(int * mib, int count){ int i; struct sysctl_dir * sysctl = sysctls; struct sysctl_dir * ret = NULL; for(i = 0; i < count; i++) { if(!(ret = sysctl = get_sysctl_entry_for_mib(mib[i], sysctl))){ gemu_log("print_syctl: can't find mib %d\n", mib[i]); return; } DPRINTF("%s.", sysctl->name); if(!(sysctl = sysctl->childs)) break; } DPRINTF("\n");}long do___sysctl(int * name, uint32_t namelen, void * oldp, size_t * oldlenp, void * newp, size_t newlen /* ignored */){ long ret = 0; int i; DPRINTF("sysctl(%p, 0x%x, %p, %p, %p, 0x%lx)\n", name, namelen, oldp, oldlenp, newp, newlen); if(name) { i = 0; do { tswap32s( name + i); } while (++i < namelen); print_syctl(name, namelen); //bswap_syctl(name, namelen, newp, newlen); tswap32s((uint32_t*)oldlenp); } if(name) /* Sometimes sysctl is called with no arg1, ignore */ ret = get_errno(sysctl(name, namelen, oldp, oldlenp, newp, newlen));#if defined(TARGET_I386) ^ defined(__i386__) || defined(TARGET_PPC) ^ defined(__ppc__) if (!is_error(ret) && bswap_syctl(name, namelen, oldp, *oldlenp) != 0) { return -ENOTDIR; }#endif if(name) { //bswap_syctl(name, namelen, newp, newlen); tswap32s((uint32_t*)oldlenp); i = 0; do { tswap32s( name + i); } while (++i < namelen); } return ret;}long do_getattrlist(void * arg1, void * arg2, void * arg3, uint32_t arg4, uint32_t arg5){ struct attrlist * attrlist = (void *)arg2; long ret;#if defined(TARGET_I386) ^ defined(__i386__) || defined(TARGET_PPC) ^ defined(__ppc__) gemu_log("SYS_getdirentriesattr unimplemented\n"); return -ENOTSUP;#endif /* XXX: don't let the %s stay in there */ DPRINTF("getattrlist(%s, %p, %p, 0x%x, 0x%x)\n", (char *)arg1, arg2, arg3, arg4, arg5); if(arg2) /* XXX: We should handle that in a copy especially if the structure is not writable */ byteswap_attrlist(attrlist); ret = get_errno(getattrlist((const char* )arg1, attrlist, (void *)arg3, arg4, arg5)); if(!is_error(ret)) { byteswap_attrbuf((void *)arg3, attrlist); byteswap_attrlist(attrlist); } return ret;}long do_getdirentriesattr(uint32_t arg1, void * arg2, void * arg3, size_t arg4, void * arg5, void * arg6, void* arg7, uint32_t arg8){ DPRINTF("getdirentriesattr(0x%x, %p, %p, 0x%lx, %p, %p, %p, 0x%x)\n", arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);#if defined(TARGET_I386) ^ defined(__i386__) || defined(TARGET_PPC) ^ defined(__ppc__) qerror("SYS_getdirentriesattr unimplemented\n");#endif return get_errno(getdirentriesattr( arg1, (struct attrlist * )arg2, (void *)arg3, arg4, (unsigned long *)arg5, (unsigned long *)arg6, (unsigned long *)arg7, arg8));}static inline void bswap_flock(struct flock *f){ tswap64s(&f->l_start); tswap64s(&f->l_len); tswap32s(&f->l_pid); tswap16s(&f->l_type); tswap16s(&f->l_whence);}static inline void bswap_fstore(struct fstore *f){ tswap32s(&f->fst_flags); tswap32s(&f->fst_posmode); tswap64s(&f->fst_offset); tswap64s(&f->fst_length); tswap64s(&f->fst_bytesalloc);}static inline void bswap_radvisory(struct radvisory *f){ tswap64s(&f->ra_offset); tswap32s(&f->ra_count);}static inline void bswap_fbootstraptransfer(struct fbootstraptransfer *f){ tswap64s(&f->fbt_offset); tswap32s((uint32_t*)&f->fbt_length); tswap32s((uint32_t*)&f->fbt_buffer); /* XXX: this is a ptr */}static inline void bswap_log2phys(struct log2phys *f){ tswap32s(&f->l2p_flags); tswap64s(&f->l2p_contigbytes); tswap64s(&f->l2p_devoffset);}static inline void bswap_fcntl_arg(int cmd, void * arg){ switch(cmd) { case F_DUPFD: case F_GETFD: case F_SETFD: case F_GETFL: case F_SETFL: case F_GETOWN: case F_SETOWN: case F_SETSIZE: case F_RDAHEAD: case F_FULLFSYNC: break; case F_GETLK: case F_SETLK: case F_SETLKW: bswap_flock(arg); break; case F_PREALLOCATE: bswap_fstore(arg); break; case F_RDADVISE: bswap_radvisory(arg); break; case F_READBOOTSTRAP: case F_WRITEBOOTSTRAP: bswap_fbootstraptransfer(arg); break; case F_LOG2PHYS: bswap_log2phys(arg); break; default: gemu_log("unknow cmd in fcntl\n"); }}long do_fcntl(int fd, int cmd, int arg){ long ret; bswap_fcntl_arg(cmd, (void *)arg); ret = get_errno(fcntl(fd, cmd, arg)); if(!is_error(ret)) bswap_fcntl_arg(cmd, (void *)arg); return ret;}long no_syscall(void *cpu_env, int num){ /* XXX: We should probably fordward it to the host kernel */ qerror("no unix syscall %d\n", num); /* not reached */ return -1;}long unimpl_unix_syscall(void *cpu_env, int num){ if( (num < 0) || (num > SYS_MAXSYSCALL-1) ) qerror("unix syscall %d is out of unix syscall bounds (0-%d) " , num, SYS_MAXSYSCALL-1); gemu_log("qemu: Unsupported unix syscall %s %d\n", unix_syscall_table[num].name , num); gdb_handlesig (cpu_env, SIGTRAP); exit(-1);}long do_unix_syscall(void *cpu_env, int num){ long ret = 0; DPRINTF("unix syscall %d: " , num); if( (num < 0) || (num > SYS_MAXSYSCALL-1) ) qerror("unix syscall %d is out of unix syscall bounds (0-%d) " , num, SYS_MAXSYSCALL-1); DPRINTF("%s [%s]", unix_syscall_table[num].name, unix_syscall_table[num].call_type & CALL_DIRECT ? "direct" : "indirect" ); ret = unix_syscall_table[num].function(cpu_env, num); if(!(unix_syscall_table[num].call_type & CALL_NOERRNO)) ret = get_errno(ret); DPRINTF("[returned 0x%x(%d)]\n", (int)ret, (int)ret); return ret;}/* ------------------------------------------------------------ syscall_init*/void syscall_init(void){ /* Nothing yet */}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -