/** * debug_print_with_prefix() - prints a debug message * * Adds, if requested by trace_flag, debug prefix in the beginning */ int debug_print_with_prefix(unsigned long trace_flag, const char *severity, const char *prefix, const char *func, int line, const char *fmt, ...) { int i; unsigned long flags; int pid = get_current_tid(); va_list args; spin_lock_irqsave(&trace_buf_lock, flags); strlcpy(trace_buf, severity, TRACE_BUF_SIZE); i = strlen(trace_buf); if (trace_flag & TRACE_PID) i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "[%d]: ", pid); if (prefix != NULL) i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%s: ", prefix); if (trace_flag & TRACE_FUNCTION) i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%s:", func); if (trace_flag & TRACE_LINE) i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%i:", line); i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%s\n", fmt); va_start(args, fmt); vprintk(trace_buf, args); va_end(args); spin_unlock_irqrestore(&trace_buf_lock, flags); return i; }
void pvm_backtrace_current_thread(void) { errno_t e = ENOENT; int tid = get_current_tid(); if( tid < 0 ) goto nope; void *owner; if( 0 != (e=t_get_owner( tid, &owner )) ) goto nope; if( 0 == owner ) goto nope; pvm_object_storage_t *_ow = owner; struct data_area_4_thread *tda = (struct data_area_4_thread *)&_ow->da; if( _ow->_class.data != pvm_get_thread_class().data ) { printf("pvm_backtrace - not thread in owner!\n"); return; } if(tda->tid != tid) { printf("pvm_backtrace VM thread TID doesn't match!\n"); return; } pvm_backtrace(tda); return; nope: printf("Unable to print backtrace, e=%d\n", e); }
void sys_close (post_id_t post){ if(get_current_tid() == Posts[post].owner){ Posts[post].owner = 0; remove_list(Posts[post].received); } }
post_id_t sys_open (void){ post_id_t p; SPIN_LOCK(alloc_post); p = alloc_post(); Posts[p].owner = get_current_tid(); Posts[p].handler = NULL; Posts[p].received = create_list(); SPIN_UNLOCK(alloc_post); return p; }
void tracing_block_begin(DECAF_Callback_Params* params) { char current_proc[512] = ""; CPUState* env = NULL; if (params != NULL) { env = params->bb.env; } /* Get thread id (needs to be done before checking hooks) */ // TODO: Are hooks checked before or after invoking block begin handler? current_tid = get_current_tid(env); // Let DECAF now that we want to hook the instructions in this block should_monitor = (decaf_plugin->monitored_cr3 == DECAF_cpu_cr[3]) && (!DECAF_is_in_kernel() || tracing_kernel()); /* If not right context, return */ if (!should_monitor) return; /* No need to check if we are tracing, otherwise block_begin unregistered */ //if ((tracepid == 0) && (!procname_is_set())) // return; /* If tracing module, check if we are in traced module */ if (modname_is_set()) { // Get current module name tmodinfo_t *mi = locate_module(*DECAF_cpu_eip, DECAF_cpu_cr[3], current_proc); // Check if right module if (mi && (modname_match(mi->name))) { tracing_start_condition = 1; modname_clear(); } } return; }
// TODO no interlock - process can be klled when we use it - use pool for processes! void syscall_sw(struct trap_state *st) { //phantom_thread_t *t = GET_CURRENT_THREAD(); //uuprocess_t *u = t->u; tid_t tid = get_current_tid(); pid_t pid; assert( !t_get_pid( tid, &pid )); uuprocess_t *u = proc_by_pid(pid); /* int ret; if( (ret = setjmp(u->signal_jmpbuf)) ) { execute_signals(u, st); return; } */ do_syscall_sw( u, st ); execute_signals(u, st); }
void tracing_insn_begin(DECAF_Callback_Params* params) { CPUState* env = NULL; if (params != NULL) { env = params->ib.env; } /* If tracing start condition not satisified, return */ if (!tracing_start_condition) return; /* If not tracing, return */ // This should not be needed, as if not tracing insn_begin unregistered // if (tracepid == 0) // return; /* If not tracing kernel and kernel instruction , return */ // This should not be needed, as should_monitor captures this condition //if ( DECAF_is_in_kernel() && !tracing_kernel() ) // return; /* Get thread id */ current_tid = get_current_tid(env); // Flag to be set if the instruction is written insn_already_written = 0; // Flag to be set if instruction accesses user memory access_user_mem = 0; /* Disassemble the instruction */ insn_tainted=0; if (skip_decode_address == 0) { decode_address(*DECAF_cpu_eip, &eh, get_st(current_tid)); } }
/*! * This is not clear how Temu define a block, however, both Hookfinder * & the sample plugin use this function to check if they are working * on the monitored process or not. */ int detector_block_begin() { // We care for nothing if (monitored_proc[0] == 0) { goto _finished; } uint32_t eip, esp, cr3; // Get the value of EIP register TEMU_read_register(eip_reg, &eip); // Get the value of CR3 register TEMU_read_register(cr3_reg, &cr3); // Get the value of ESP register TEMU_read_register(esp_reg, &esp); // Get the current process using the above registers tmodinfo_t * mi = locate_module(eip, cr3, current_proc); // Get the current working module inside the current process strcpy(current_mod, mi ? mi->name : "<unknown>"); if (0x00 == strcasecmp(current_mod, monitored_proc)) { // Save the base address checked_module_base = mi->base; // Save the size checked_module_size = mi->size; // We are inside the monitored module in_checked_module = LOC_INSIDE; goto _handle; } uint32_t phys_addr = TEMU_get_phys_addr(eip); // Check what ? taint_record_t records[0x04]; uint64_t taint = taintcheck_memory_check(phys_addr, 1, (uint8_t *) records); if (taint) { // This may be generated code in_checked_module = LOC_GEN; // Log fprintf( loghandle, "Tainted code: %s!%s eip=%08x\n", current_proc, mi ? mi->name: "<unknown>", eip); goto _handle; } // Get the id of the current thread current_thread_id = get_current_tid(); // Get the information about the current thread current_thread_node = (current_thread_id != -1UL) ? get_thread_info(current_thread_id) : NULL; // In system call if (current_thread_node) { if (current_thread_node->origin == 1 || current_thread_node->origin == 2) { // Jump out of malicious code if (((current_thread_node->esp & 0x80000000) == (esp & 0x80000000)) && (current_thread_node->esp < esp)) { // Return from malware delete_thread_info(current_thread_id); current_thread_node = NULL; goto _finished; } if (((current_thread_node->esp & 0x80000000) == (esp & 0x80000000)) && (current_thread_node->esp > esp)) { // External call - set the caller current_thread_node->entry_eip = eip; // Follow the Hookfinder style current_thread_node->origin = 3; goto _finished; } } } // Skip the rest goto _finished; _handle: // This is not the monitored process if(current_thread_id == -1UL) { goto _finished; } // Set the current thread info if (! current_thread_node) { thread_info_t info; // Zero-out bzero( &info, sizeof(info) ); // Set its members info.cr3 = cr3; info.esp = esp; // Why set its value to 0 ? info.eip = 0x00; info.origin = (uint32_t)in_checked_module; // Save the thread info write_thread_info(current_thread_id, &info); // and refer to the newly updated current thread current_thread_node = get_thread_info(current_thread_id); } current_thread_node->eip = 0; current_thread_node->out_eip = 0; current_thread_node->entry_eip = 0; current_thread_node->origin = (uint32_t)in_checked_module; _finished: //we should always check if there is a hook at this point, //no matter we are in the monitored context or not, because //some hooks are global. hookapi_check_call(should_monitor); // Thread ? in_checked_module = current_thread_node ? (enum location_t)current_thread_node->origin : LOC_NOWHERE; // Done return 0; }
static void do_syscall_sw( uuprocess_t *u, struct trap_state *st) { #if HAVE_UNIX int callno = st->eax; /* unsigned int mina = 0, maxa = 0; { extern struct real_descriptor ldt[]; struct real_descriptor dsd = ldt[ st->ds/8 ]; mina = dsd.base_low | (dsd.base_med << 16) | (dsd.base_high << 24); maxa = (dsd.limit_low | dsd.limit_high << 16); if( dsd.granularity & SZ_G) maxa *= PAGE_SIZE; maxa += mina; } */ //phantom_thread_t *t = GET_CURRENT_THREAD(); //uuprocess_t *u = t->u; /* tid_t tid = get_current_tid(); pid_t pid; assert( !t_get_pid( tid, &pid )); uuprocess_t *u = proc_by_pid(pid); */ assert( u != 0 ); unsigned int mina = (int)u->mem_start, maxa = (int)u->mem_end; // trap state is good for interrupt. // call gate does not push eflags int user_esp = st->eflags; #ifndef ARCH_ia32 # warning machdep ia32 arg pass convention #endif // list of user syscsall arguments int *uarg = adjustin( user_esp, st ); uarg++; // syscall func return addr //SHOW_FLOW( 10, "Syscall pid %2d tid %2d, our esp %p, user esp %p, t kstack %p", u->pid, t->tid, &st, user_esp, t->kstack_top ); SHOW_FLOW( 8, "Syscall %d args %x, %x, %x", callno, uarg[0], uarg[1],uarg[2] ); int ret = 0; int err = 0; switch(callno) { case SYS__exit: // TODO housekeeping? SHOW_FLOW( 2, "exit %d", uarg[0] ); hal_exit_kernel_thread(); err = ENOSYS; break; case SYS_ssyslog: syslog( uarg[0], "%s", (const char *)adjustin( uarg[1], st ) ); SHOW_FLOW( 2, "syslog %d %s", uarg[0], (const char *)adjustin( uarg[1], st ) ); //SHOW_ERROR0( 0, "syslog not impl" ); break; case SYS_sleepmsec: //SHOW_FLOW( 2, "sleepmsec %d", uarg[0] ); hal_sleep_msec(uarg[0]); break; case SYS_getpagesize: ret = PAGE_SIZE; break; case SYS_personality: if( ((unsigned) uarg[0]) == 0xffffffff) { ret = 0; // Say we're Linux... well...to some extent. break; } err = EINVAL; break; case SYS_uname: err = copyout(uarg[0], mina, maxa, &phantom_uname, sizeof(phantom_uname) ); if( err ) ret = -1; break; case SYS_getuid: ret = u->uid; break; case SYS_getuid32: ret = u->uid;; break; case SYS_getegid: ret = u->egid; break; case SYS_getegid32: ret = u->egid; break; case SYS_geteuid: ret = u->euid; break; case SYS_geteuid32: ret = u->euid; break; case SYS_getgid: ret = u->gid; break; case SYS_getgid32: ret = u->gid; break; case SYS_gettid: ret = get_current_tid(); break; case SYS_getpid: ret = u->pid; break; case SYS_getpgrp: ret = u->pgrp_pid; break; case SYS_getppid: ret = u->ppid; break; case SYS_getpgid: goto unimpl; case SYS_time: { time_t t = time(0); AARG(time_t *, tp, 0, sizeof(time_t)); *tp = t; ret = t; break; } case SYS_nanosleep: // todo check for POSIX compliance, make it interruptible by signals //int nanosleep(const struct timespec *, struct timespec *); { goto unimpl; //AARG(struct timespec *, req_time, 0, sizeof(struct timespec)); //AARG(struct timespec *, rest_time, 1, sizeof(struct timespec)); //ret = usys_nanosleep( &err, u, req_time, rest_time ); //break; } case SYS_sync: case SYS_sysinfo: case SYS_sysfs: case SYS_klogctl: case SYS_shutdown: case SYS_reboot: case SYS_getitimer: case SYS_setitimer: case SYS_gettimeofday: case SYS_setuid: case SYS_setuid32: CHECK_CAP(CAP_SETUID); u->euid = uarg[0]; break; case SYS_setgid: case SYS_setgid32: CHECK_CAP(CAP_SETGID); u->egid = uarg[0]; break; case SYS_setgroups: case SYS_setgroups32: goto unimpl; case SYS_setpgid: case SYS_setregid: case SYS_setregid32: case SYS_setresgid: case SYS_setresgid32: case SYS_setresuid: case SYS_setresuid32: case SYS_setreuid: case SYS_setreuid32: goto unimpl; case SYS_open: ret = usys_open(&err, u, adjustin( uarg[0], st ), uarg[1], uarg[2] ); break; case SYS_close: ret = usys_close(&err, u, uarg[0] ); break; case SYS_read: { int count = uarg[2]; void *addr = adjustin( uarg[1], st ); CHECKA(addr,count); ret = usys_read(&err, u, uarg[0], addr, count ); break; } case SYS_write: { int count = uarg[2]; void *addr = adjustin( uarg[1], st ); CHECKA(addr,count); ret = usys_write(&err, u, uarg[0], addr, count ); break; } case SYS_lseek: ret = usys_lseek(&err, u, uarg[0], uarg[1], uarg[2] ); break; case SYS_creat: ret = usys_creat(&err, u, adjustin( uarg[0], st ), uarg[1] ); break; case SYS_chdir: { AARG(const char *, path, 0, 0); ret = usys_chdir(&err, u, path ); break; } case SYS_pipe: { AARG(int *, fds, 0, sizeof(int) * 2); ret = usys_pipe( &err, u, fds ); break; } case SYS_rmdir: case SYS_unlink: { AARG(const char *, name, 0, 1); ret = usys_rm( &err, u, name ); break; } case SYS_dup: ret = usys_dup( &err, u, uarg[0] ); break; case SYS_dup2: ret = usys_dup2( &err, u, uarg[0], uarg[1] ); break; case SYS_symlink: { AARG(const char *, n1, 0, 1); AARG(const char *, n2, 1, 1); ret = usys_symlink( &err, u, n1, n2 ); break; } case SYS_getcwd: { AARG(char *, buf, 0, uarg[1]); ret = usys_getcwd( &err, u, buf, uarg[1] ); break; } case SYS_mkdir: { AARG(const char *, path, 0, 2); ret = usys_mkdir( &err, u, path ); break; } case SYS_link: case SYS__llseek: case SYS_chroot: case SYS_lstat64: case SYS_mknod: goto unimpl; case SYS_mount: { const char *source = adjustin( uarg[0], st ); CHECKA(source,0); const char *target = adjustin( uarg[1], st ); CHECKA(target,0); const char *fstype = adjustin( uarg[2], st ); CHECKA(target,0); const void *data = adjustin( uarg[4], st ); CHECKA(data,0); ret = usys_mount(&err, u, source, target, fstype, uarg[3], data ); break; } case SYS_umount: { const char *target = adjustin( uarg[0], st ); CHECKA(target,0); ret = usys_umount(&err, u, target, 0 ); break; } /* case SYS_umount2: { const char *target = adjustin( uarg[0], st ); CHECKA(target); ret = usys_umount(&err, u, target, uarg[1] ); break; } */ case SYS_truncate: { AARG(const char *, path, 0, 0); ret = usys_truncate(&err, u, path, uarg[1] ); break; } case SYS_ftruncate: { ret = usys_ftruncate(&err, u, uarg[0], uarg[1] ); break; } case SYS_truncate64: case SYS_ftruncate64: goto unimpl; case SYS_fchdir: ret = usys_fchdir( &err, u, uarg[0] ); break; case SYS_readdir: { AARG(struct dirent *, ent, 1, sizeof(struct dirent)); ret = usys_readdir( &err, u, uarg[0], ent ); break; } case SYS_fchmod: ret = usys_fchmod( &err, u, uarg[0], uarg[1] ); break; case SYS_fchown: case SYS_fchown32: ret = usys_fchown( &err, u, uarg[0], uarg[1], uarg[2] ); break; case SYS_fcntl: { //AARG(void *, str, 2, sizeof(int)); // FIXME size of arg? ret = usys_fcntl( &err, u, uarg[0], uarg[1], uarg[0] ); } break; case SYS_fcntl64: case SYS_fdatasync: case SYS_flock: case SYS_fstat64: case SYS_fstatfs: case SYS_fsync: case SYS_utime: case SYS_chmod: case SYS_chown: case SYS_chown32: case SYS_access: case SYS_lchown: case SYS_lchown32: case SYS_pread: case SYS_pwrite: goto unimpl; case SYS_readv: { int fd = uarg[0]; int iovcnt = uarg[2]; AARG(struct iovec *, list, 1, sizeof(struct iovec) * iovcnt); unsigned int onerc; int lp; for( lp = 0; lp < iovcnt; lp++ ) { void *addr = adjustin( list[lp].iov_base, st ); CHECKA(addr,list[lp].iov_len); onerc = usys_read(&err, u, fd, addr, list[lp].iov_len ); /* if( onerc < 0 ) { ret = -1; goto err_ret; } */ ret += onerc; if( onerc < list[lp].iov_len ) break; } break; } case SYS_writev: { int fd = uarg[0]; int iovcnt = uarg[2]; AARG(struct iovec *, list, 1, sizeof(struct iovec) * iovcnt); unsigned int onerc; int lp; for( lp = 0; lp < iovcnt; lp++ ) { void *addr = adjustin( list[lp].iov_base, st ); CHECKA(addr,list[lp].iov_len); onerc = usys_write(&err, u, fd, addr, list[lp].iov_len ); /* if( onerc < 0 ) { ret = -1; goto err_ret; } */ ret += onerc; if( onerc < list[lp].iov_len ) break; } break; } case SYS_readlink: goto unimpl; case SYS_gethostname: { int len = uarg[1]; char *target = adjustin( uarg[0], st ); CHECKA(target,len); ret = usys_gethostname(&err, u, target, len ); break; } case SYS_sethostname: { int len = uarg[1]; const char *target = adjustin( uarg[0], st ); CHECKA(target,len); ret = usys_sethostname(&err, u, target, len ); break; } case SYS_socket: ret = usys_socket( &err, u, uarg[0], uarg[1], uarg[2] ); break; case SYS_setsockopt: { socklen_t optlen = uarg[4]; AARG(const void *, optval, 3, optlen); ret = usys_setsockopt( &err, u, uarg[0], uarg[1], uarg[2], optval, optlen); break; } case SYS_getsockopt: { AARG(socklen_t *, optlen, 4, sizeof(socklen_t)); AARG(void *, optval, 3, *optlen); ret = usys_getsockopt( &err, u, uarg[0], uarg[1], uarg[2], optval, optlen); break; } case SYS_getpeername: { AARG(socklen_t *, namelen, 2, sizeof(socklen_t)); AARG(struct sockaddr *, name, 1, *namelen); ret = usys_getpeername( &err, u, uarg[0], name, namelen); break; } case SYS_getsockname: { AARG(socklen_t *, namelen, 2, sizeof(socklen_t)); AARG(struct sockaddr *, name, 1, *namelen); ret = usys_getsockname( &err, u, uarg[0], name, namelen); break; } case SYS_bind: { AARG(const struct sockaddr *, addr, 1, sizeof(struct sockaddr)); ret = usys_bind( &err, u, uarg[0], addr, uarg[2] ); break; } case SYS_listen: ret = usys_listen( &err, u, uarg[0], uarg[1] ); break; case SYS_accept: { AARG( socklen_t *, len, 2, sizeof(socklen_t)); AARG( struct sockaddr *, acc_addr, 1, *len ); ret = usys_accept( &err, u, uarg[0], acc_addr, len ); break; } case SYS_recv: { int len = uarg[2]; AARG( void *, buf, 0, len ); ret = usys_recv( &err, u, uarg[0], buf, len, uarg[3] ); break; } case SYS_recvmsg: { AARG( struct msghdr *, msg, 0, sizeof(struct msghdr) ); ret = usys_recvmsg( &err, u, uarg[0], msg, uarg[2] ); break; } case SYS_send: { int len = uarg[2]; AARG( const void *, buf, 0, len ); ret = usys_send( &err, u, uarg[0], buf, len, uarg[3] ); break; } case SYS_sendmsg: { AARG( const struct msghdr *, msg, 0, sizeof(struct msghdr) ); ret = usys_sendmsg( &err, u, uarg[0], msg, uarg[2] ); break; } case SYS_sendto: { socklen_t tolen = uarg[5]; AARG( const struct sockaddr *, to, 4, tolen ); int len = uarg[2]; AARG( const void *, buf, 0, len ); ret = usys_sendto( &err, u, uarg[0], buf, len, uarg[3], to, tolen ); break; } case SYS_recvfrom: { AARG( socklen_t *, fromlen, 5, sizeof(socklen_t) ); AARG( struct sockaddr *, from, 4, *fromlen ); int len = uarg[2]; AARG( void *, buf, 0, len ); ret = usys_recvfrom( &err, u, uarg[0], buf, len, uarg[3], from, fromlen ); break; } case SYS_connect: // int connect(int socket, const struct sockaddr *address, socklen_t address_len); { int len = uarg[2]; AARG( struct sockaddr *, acc_addr, 1, len ); ret = usys_connect( &err, u, uarg[0], acc_addr, len ); break; } case SYS_socketpair: { AARG( int *, sv, 3, sizeof(int) * 2 ); ret = usys_socketpair( &err, u, uarg[0], uarg[1], uarg[2], sv ); break; } case SYS_sendfile: case SYS_socketcall: goto unimpl; case SYS_nice: { // int nice = uarg[0]; // set thr prio // break; goto unimpl; } case SYS_brk: goto unimpl; /*{ ret = usys_sbrk( &err, u, uarg[0] ); break; }*/ case SYS_fork: case SYS_vfork: goto unimpl; case SYS_ioctl: { void *data = adjustin( uarg[2], st ); CHECKA(data,0); ret = usys_ioctl( &err, u, uarg[0], uarg[1], data, uarg[3] ); break; } int statlink; case SYS_lstat: statlink = 1; goto dostat; case SYS_stat: statlink = 0; goto dostat; dostat: { const char *path = adjustin( uarg[0], st ); CHECKA(path,0); struct stat *data = adjustin( uarg[1], st ); CHECKA(data,sizeof(struct stat)); ret = usys_stat( &err, u, path, data, statlink ); break; } case SYS_fstat: { struct stat *data = adjustin( uarg[1], st ); CHECKA(data,sizeof(struct stat)); ret = usys_fstat( &err, u, uarg[0], data, 0 ); break; } case SYS_umask: { ret = u->umask; u->umask = uarg[0]; break; } case SYS_kill: { ret = usys_kill( &err, u, uarg[0], uarg[1] ); break; } case SYS_waitpid: { AARG(int *, addr, 1, sizeof(int)); ret = usys_waitpid( &err, u, uarg[0], addr, uarg[2] ); break; } case SYS_wait: { AARG(int *, addr, 0, sizeof(int)); ret = usys_waitpid( &err, u, -1, addr, 0 ); break; } case SYS_clone: goto unimpl; case SYS_madvise: case SYS_mincore: case SYS_mlock: case SYS_mlockall: case SYS_mmap: case SYS_mprotect: case SYS_mremap: case SYS_msync: case SYS_munlock: case SYS_munlockall: case SYS_munmap: goto unimpl; // NewOS/BeOS/Haiku case SYS_create_port: { // TODO check string length and final addr to be valid AARG(const char *, name, 1, 0); ret = port_create( uarg[0], name ); break; } case SYS_close_port: ret = port_close( uarg[0] ); break; case SYS_delete_port: ret = port_delete( uarg[0] ); break; case SYS_find_port: { // TODO check string length and final addr to be valid AARG(const char *, name, 0, 0); ret = port_find(name); break; } case SYS_get_port_info: { AARG(struct port_info *, info, 1, sizeof(struct port_info)); ret = port_get_info( uarg[0], info); } case SYS_get_port_bufsize: ret = port_buffer_size( uarg[0] ); break; case SYS_get_port_bufsize_etc: ret = port_buffer_size_etc( uarg[0], uarg[1], uarg[2] ); break; case SYS_get_port_count: ret = port_count( uarg[0] ); break; case SYS_read_port: { AARG(int32_t *, msg_code, 1, sizeof(int32_t)); AARG(void *, msg_buffer, 2, uarg[3]); ret = port_read( uarg[0], msg_code, msg_buffer, uarg[3]); break; } case SYS_write_port: { //AARG(int32_t *, msg_code, 1, sizeof(int32_t)); //AARG(int32_t, msg_code, 1, sizeof(int32_t)); AARG(void *, msg_buffer, 2, uarg[3]); ret = port_write( uarg[0], uarg[1], msg_buffer, uarg[3]); break; } case SYS_read_port_etc: case SYS_write_port_etc: case SYS_set_port_owner: case SYS_get_next_port_info: goto unimpl; case SYS_phantom_run: { // extern int phantom_run(const char *fname, const char **argv, const char **envp, int flags); AARG(const char *, fname, 0, 1); AARG(const char **, uav, 1, 4); AARG(const char **, uep, 2, 4); if( 0 == uarg[1] ) uav = 0; if( 0 == uarg[2] ) uep = 0; SHOW_FLOW( 2, "run %s flags 0x%b", fname, uarg[3], "\020\1<WAIT>\2<NEWWIN>\3<NEWPGRP>" ); char *a[1024]; char *e[1024]; SHOW_FLOW( 2, "run %s load args", fname ); if( user_args_load( mina, maxa, a, 1024, uav ) || user_args_load( mina, maxa, e, 1024, uep ) ) { ret = -1; err = EFAULT; SHOW_ERROR( 0, "fault reading args for %s", fname ); goto err_ret; } ret = usys_run( &err, u, fname, (const char**)a, (const char**)e, uarg[3] ); break; } case SYS_phantom_method: // AARG(const char *, m_name, 0, 1); // int nfd = aarg[1]; // AARG(int *, fds, 0, sizeof(int)*nfd); // ret = usys_pmethod( &err, u, m_name, int nfd, int fds[] ); case SYS_phantom_toobject: case SYS_phantom_fromobject: case SYS_phantom_intmethod: case SYS_phantom_strmethod: goto unimpl; // extern int phantom_runclass(const char *cname, int nmethod, int flags); case SYS_phantom_runclass: { AARG(const char *, cname, 0, 1); unsigned flags = uarg[2]; if(flags) SHOW_ERROR( 0, "SYS_phantom_runclass: unknown flags %x" , flags ); usys_phantom_runclass( &err, u, cname, uarg[1] ); ret = err; } break; case SYS_setproperty: { AARG(const char *, pName, 1, 1); // TODO check zero term string! AARG(const char *, pValue, 2, 1); usys_setproperty( &err, u, uarg[0], pName, pValue ); ret = err; } break; case SYS_getproperty: { AARG(const char *, pName, 1, 1); // TODO check zero term string! AARG(char *, pValue, 2, uarg[3]); usys_getproperty( &err, u, uarg[0], pName, pValue, uarg[3] ); ret = err; } break; case SYS_listproperties: { AARG(char *, buf, 2, uarg[3]); usys_listproperties( &err, u, uarg[0], uarg[1], buf, uarg[3] ); ret = err; } break; case SYS_name2ip: { AARG(in_addr_t *, out, 0, sizeof(in_addr_t)); AARG(const char *, name, 1, 1); ret = name2ip( out, name, uarg[2] ); if( ret != 0 ) err = ret; } break; case SYS_sigpending: { AARG(sigset_t *, set, 0, sizeof(sigset_t *)); ret = usys_sigpending( &err, u, set); break; } case SYS_signal: { #if 0 AARG(sighandler_t, hand, 1, sizeof(sighandler_t)); hand = usys_signal( &err, u, uarg[0], hand); // FIXME 64 bit error ret = ((int)hand) - mina; // Convert pointer back #else // We do not use pointer (ret and uarg 1), so we don't have to convert it ret = (int)usys_signal( &err, u, uarg[0], (void *)uarg[1]); #endif break; } case SYS_sigprocmask: //case raise: case SYS_sigaction: case SYS_siginterrupt: case SYS_sigsuspend: goto unimpl; unimpl: SHOW_ERROR( 0, "Unimplemented syscall %d called", callno ); err = ENOSYS; break; default: SHOW_ERROR( 0, "Unknown syscall %d called", callno ); err = ENOSYS; break; } #else // HAVE_UNIX int err = ENOSYS; int ret = -1; goto err_ret; // to clear warning #endif // HAVE_UNIX err_ret: #ifdef ARCH_ia32 #define _RET_OK st->eax = ret; st->edx = err; #endif #ifdef ARCH_mips #define _RET_OK st->r2 = ret; // v0 (normal ret register, low) st->r3 = err; // v1 (normal ret register, hi) #endif #ifdef ARCH_arm #define _RET_OK st->r0 = ret; // normal ret register st->r1 = err; // arg1 reg, we can safely use for return of errno #endif #ifndef _RET_OK #error arch ret #endif }
static void phantom_debug_window_loop() { static char buf[DEBBS+1]; int step = 0; int show = 's'; t_current_set_name("Debug Win"); // Which thread will receive typein for this window phantom_debug_window->owner = get_current_tid(); int wx = 600; #if CONF_NEW_CTTY if( t_new_ctty( get_current_tid() ) ) panic("console t_new_ctty"); #else // Need separate ctty t_set_ctty( get_current_tid(), wtty_init( WTTY_SMALL_BUF ) ); #endif // TODO HACK! Need ioctl to check num of bytes? wtty_t *tty; t_get_ctty( get_current_tid(), &tty ); while(1) { if(tty && !wtty_is_empty(tty)) { char c = wtty_getc( tty ); switch(c) { case '?': case'h': printf( "Commands:\n" "---------\n" "w\t- show windows list\n" "t\t- show threads list\n" "s\t- show stats\n" "p\t- show profiler\n" "d\t- dump threads to JSON\n" ); break; case 'p': // profiler case 't': //w_set_title( phantom_debug_window, "Threads" ); //show = c; //break; case 'w': //w_set_title( phantom_debug_window, "Windows" ); //show = c; //break; case 's': //w_set_title( phantom_debug_window, "Stats" ); show = c; break; case 'd': { json_output jo = { 0 }; json_start( &jo ); json_dump_threads( &jo ); json_stop( &jo ); } break; } } { static char old_show = 0; if( old_show != show ) { old_show = show; switch(show) { case 't': w_set_title( phantom_debug_window, "Threads" ); break; case 'w': w_set_title( phantom_debug_window, "Windows" ); break; case 's': w_set_title( phantom_debug_window, "Stats" ); break; case 'p': w_set_title( phantom_debug_window, "Profiler" ); break; } } } //hal_sleep_msec(1000); hal_sleep_msec(100); #if 1 #if 1 w_clear( phantom_debug_window ); ttyd = DEBWIN_YS-20; ttxd = 0; #endif //put_progress(); void *bp = buf; int len = DEBBS; int rc; time_t sec = uptime(); int min = sec/60; sec %= 60; int hr = min/60; min %= 60; int days = hr/24; hr %= 24; struct tm mt = *current_time; rc = snprintf(bp, len, " View: \x1b[32mt\x1b[37mhreads \x1b[32ms\x1b[37mtats \x1b[32mw\x1b[37mindows \x1b[32mp\x1b[37mrofile \x1b[32m?\x1b[37m - help\n \x1b[32mStep %d, uptime %dd, %02d:%02d:%02d\x1b[37m, %d events\n Time %04d/%02d/%02d %02d:%02d:%02d GMT, CPU 0 %2d%% idle\n", step++, days, hr, min, (int)sec, ev_get_n_events_in_q(), mt.tm_year + 1900, mt.tm_mon, mt.tm_mday, mt.tm_hour, mt.tm_min, mt.tm_sec, 100-percpu_cpu_load[0] ); bp += rc; len -= rc; switch(show) { case 't': default: phantom_dump_threads_buf(bp,len); break; case 'w': phantom_dump_windows_buf(bp,len); break; case 's': phantom_dump_stats_buf(bp,len); break; case 'p': phantom_dump_profiler_buf(bp,len); break; } phantom_debug_window_puts(buf); if(wx == 600) wx = 620; else wx = 600; //w_move( phantom_debug_window, wx, 50 ); #endif put_progress(); w_update( phantom_debug_window ); } }
void phantom_init_console_window() { hal_mutex_init( &buf_mutex, "console" ); console_fg = COLOR_LIGHTGRAY; console_bg = COLOR_BLACK; int xsize = 620, ysize = 300; int cw_x = 50, cw_y = 450; if( scr_get_ysize() < 600 ) { cw_x = cw_y = 0; } drv_video_window_t *w = drv_video_window_create( xsize, ysize, cw_x, cw_y, console_bg, "Console", WFLAG_WIN_DECORATED|WFLAG_WIN_DOUBLEBUF ); phantom_console_window = w; w->owner = get_current_tid(); phantom_set_console_ops( &win_ops ); phantom_console_window_puts("Phantom console window\n"); phantom_debug_window = drv_video_window_create( DEBWIN_XS, DEBWIN_YS, DEBWIN_X, DEBWIN_Y, console_bg, "Threads", WFLAG_WIN_DECORATED|WFLAG_WIN_DOUBLEBUF|WFLAG_WIN_FULLPAINT ); //phantom_debug_window->flags |= WFLAG_WIN_DOUBLEBUF|WFLAG_WIN_FULLPAINT; //w_update( phantom_debug_window ); // For dbl buf flags to start working ok phantom_debug_window_puts("Phantom debug window\n\nt - threads\nw - windows\ns - stats\np - profiler\n"); w_update( phantom_debug_window ); //hal_sleep_msec(4000); hal_start_kernel_thread(phantom_debug_window_loop); // ------------------------------------------------------------------- // Launcher window // ------------------------------------------------------------------- color_t la_bg = { 0x19, 0x19, 0x19, 0xFF }; color_t la_b1 = { 68, 66, 62, 0xFF }; color_t la_b2 = { 88, 84, 79, 0xFF }; color_t la_txt = { 0x11, 0xd5, 0xff, 0xFF }; //#define BTEXT_COLOR COLOR_YELLOW #define BTEXT_COLOR la_txt phantom_launcher_window = drv_video_window_create( scr_get_xsize(), 32, 0, 0, console_bg, "Launcher", WFLAG_WIN_ONTOP ); phantom_launcher_window->inKernelEventProcess = phantom_launcher_event_process; w_fill( phantom_launcher_window, la_bg ); int lb_x = scr_get_xsize(); lb_x -= power_button_sm_bmp.xsize + 5; w_add_button( phantom_launcher_window, -1, lb_x, 2, &power_button_sm_bmp, &power_button_pressed_sm_bmp, BUTTON_FLAG_NOBORDER ); pool_handle_t bh; lb_x = 5; int nwin = 0; for( nwin = 0; nwin < MAX_LAUNCH_BUTTONS; nwin++ ) { char * wname = "win1"; // crashes in some configurations?? //wname[3] = '0' + nwin; bh = w_add_button( phantom_launcher_window, nwin, lb_x, 5, &task_button_bmp, &task_button_bmp, BUTTON_FLAG_NOBORDER ); w_button_set_text( phantom_launcher_window, bh, wname, BTEXT_COLOR ); lb_x += 5+task_button_bmp.xsize; taskbuttons[nwin] = bh; } w_draw_line( phantom_launcher_window, 0, 31, scr_get_xsize(), 31, la_b1 ); w_draw_line( phantom_launcher_window, 0, 30, scr_get_xsize(), 30, la_b2 ); w_update( phantom_launcher_window ); //hal_start_kernel_thread(phantom_launcher_window_loop); }
void sys_send (struct msg *m, options_t options){ if(get_current_tid() == Posts[post].owner){ if(Threads[Posts[m->dest].owner].vm == Threads[Posts[m->from].owner].vm){ if(m->dest > POST_NUM_MAX || Posts[m->dest].owner == 0){ // TODO: send a error msg } prepend_to_list(Posts[m->dest].received, m); wake_thread(Posts[m->dest].owner); }else{ // TODO: move a page of a message to dest if(Posts[m->dest].handler == NULL){ // TODO: prepend_to_list(Posts[m->dest].received, m); }else{ // TODO: create thread and call handler } } } struct msg *sys_recv (post_id_t post, options_t options){ struct msg *m; if(get_current_tid() != Posts[post].owner) return NULL; if(is_list_empty(Posts[post].received)){ if(options & MSG_NOWAIT) return NULL; // wait for a message sleep_thread(Posts[m->dest].owner); } Posts[post].received = pop_from_list(Posts[post].received, (void *) &m); return m; } void sys_await (post_id_t post, void (*handler)(struct msg *m), uintmax_t max_thread_num){ if(get_current_tid() != Posts[post].owner) return; Posts[post].handler = handler; Posts[post].max_thread_num = max_thread_max; } struct msg *compose (size_t body_size){ return allocate_memory_block(sizeof(struct msg) + body_size); } void discard (struct msg *m){ free_memory_block(m); }