void cmd_elf(char *arg) { int fd, ret; struct file *fp; int isElf; elf_header_t header; fd = call_syscall(5, (uintptr_t) arg, 0, 0); if (fd <= 0) { _printk("open failed: %d\n", fd); return; } fp = current->owner->file_table[fd]; isElf = elf_probe(fp); _printk("file(%d) is %sELF\n", fd, isElf ? "" : "not "); if (!isElf) { call_syscall(6, fd, 0, 0); return; } fp->fops->read(fp, &header, sizeof(elf_header_t)); _printk("ELF Type: %s\n", elf_type_as_string(header.e_type)); _printk("Entry Point: 0x%x\n", header.e_entry); ret = elf_load(fp); _printk("ELF RET: %s\n", errno_to_string(ret)); }
void cmd_cat(char *arg) { int fd; char *buf; struct stat st; int ret; ret = call_syscall(18, (uintptr_t) arg, (uintptr_t) &st, 0); if (ret < 0) { _printk("Error while stat: %d\n", ret); return; } buf = kmalloc(st.st_size); fd = call_syscall(5, (uintptr_t) arg, 0, 0); if (fd <= 0) { _printk("open failed\n"); return; } ret = call_syscall(3, fd, (uintptr_t) buf, st.st_size); call_syscall(4, 1, (uintptr_t) buf, st.st_size); }
void cmd_stat(char *arg) { struct stat st; int ret; ret = call_syscall(18, (uintptr_t) arg, (uintptr_t) &st, 0); if (ret < 0) { _printk("Error while stat: %d\n", ret); return; } _printk("File: %s\n", arg); _printk("Size: %d bytes\n", st.st_size); }
static void syscall_handler(registers_t regs) { if (regs.eax >= num_syscalls) { return; } call_syscall( syscall[regs.eax], regs.ebx, regs.ecx, regs.edx, regs.esi, regs.edi ); }
int main(int argc, char *argv[]) { struct syscall_desc *scall; unsigned int n; char *gids, *endp; int uid, umsk, ch; uid = -1; gids = NULL; umsk = 0; while ((ch = getopt(argc, argv, "g:u:U:")) != -1) { switch(ch) { case 'g': gids = optarg; break; case 'u': uid = (int)strtol(optarg, &endp, 0); if (*endp != '\0' && !isspace((unsigned char)*endp)) { fprintf(stderr, "invalid uid '%s' - number " "expected\n", optarg); exit(1); } break; case 'U': umsk = (int)strtol(optarg, &endp, 0); if (*endp != '\0' && !isspace((unsigned char)*endp)) { fprintf(stderr, "invalid umask '%s' - number " "expected\n", optarg); exit(1); } break; default: usage(); } } argc -= optind; argv += optind; if (argc < 1) { fprintf(stderr, "too few arguments\n"); usage(); } if (gids != NULL) { fprintf(stderr, "changing groups to %s\n", gids); set_gids(gids); } if (uid != -1) { fprintf(stderr, "changing uid to %d\n", uid); if (setuid(uid) < 0) { fprintf(stderr, "cannot change uid: %s\n", strerror(errno)); exit(1); } } /* Change umask to requested value or to 0, if not requested. */ umask(umsk); for (;;) { scall = find_syscall(argv[0]); if (scall == NULL) { fprintf(stderr, "syscall '%s' not supported\n", argv[0]); exit(1); } argc--; argv++; n = call_syscall(scall, argv); argc -= n; argv += n; if (argv[0] == NULL) break; argc--; argv++; } /* Close the descriptors left open */ while (ndescriptors > 0) { close(descriptor_get(ndescriptors - 1)); ndescriptors--; } exit(0); }
static void __cmd_testmt_2() { while (__i_ ++ < 1000) { _printk("%d\n", __i_); if (!(__i_ % 100)) schedule_noirq(); } call_syscall(1, 0, 0, 0);}
static void __cmd_testmt_1() { while (__i_ -= 100 > 0) _printk("%d\n", __i_); call_syscall(1, 0, 0, 0);}
void cmd_exit() { call_syscall(1, 0, 0, 0); }
/* * メッセージ受信 (タイムアウト機能つき) */ ER trcv_mbf (VP msg, INT *size, ID id, TMO tmout) { return (call_syscall (SYS_TRCV_MBF, msg, size, id, tmout)); }
ER prcv_mbf (VP msg, INT *size, ID id) { return (call_syscall (SYS_PRCV_MBF, msg, size, id)); }
/* * メッセージの送信 (タイムアウト機能つき) */ ER tsnd_mbf (ID id, INT size, VP msg, TMO tmout) { return (call_syscall (SYS_TSND_MBF, id, size, msg, tmout)); }
/* * メッセージの送信 (ポーリング機能つき) */ ER psnd_mbf (ID id, INT size, VP msg) { return (call_syscall (SYS_PSND_MBF, id, size, msg)); }
/* * メッセージバッファの削除 */ ER del_mbf (ID id) { return (call_syscall (SYS_DEL_MBF, id)); }
/* * メッセージバッファの作成 */ ER cre_mbf (ID id, T_CMBF *pk_cmbf) { return (call_syscall (SYS_CRE_MBF, id, pk_cmbf)); }
SCOPE void wrapped_syscall(const struct syscall_regs r) { /* if we don't trace fork and clone, the * child process can set tracing to 0 */ if (!tracing) { uint32_t retval; call_syscall(r, retval); return; } /* we must set signal_regs very early. if we set it * inside ENTER/EXIT_SYSCALL, a signal may happen before this assignment. */ /* don't check IS_BREAK_SYSCALL. we allow embeded signal handler. */ /* if a signal raise, we will use signal_regs immediately. so don't worry about * override. (the signal handler will save this regs before any new syscall, and * the restorer needn't it). */ signal_regs = &r; /* if a signal raise outside a syscall, those 2 values should same. if not, thay are * different. */ __syscall_reenter_base = __syscall_reenter_counter; /* if a signal happened after this gate and before EXIT_SYSCALL, * we know this syscall is disturbed, when sigprocess making ckpts, * it needs to adjust registers. */ /* don't allow signal inside before_syscall. * if signal happened inside it, the logger may be disturbed. */ /* disable dignal before enter_syscall make sure the sysall's header * is written into log when potential signal raise */ DISABLE_SIGNAL(); ENTER_SYSCALL(); if (!replay) { uint32_t syscall_nr = r.orig_eax; INJ_SILENT("wrapped_syscall: %d\n", syscall_nr); before_syscall(&r); ENABLE_SIGNAL(); uint32_t retval; call_syscall(r, retval); DISABLE_SIGNAL(); /* write a flag to indicate syscall not be disturbed */ /* if this syscall disturbed, the next data in logger * may be a syscall_nr (if signal processing use syscall) or a -2 * (write by wrapped_(rt_)sigreturn). when replay, if see this -1, * we know this syscall ends normally. */ int16_t f = -1; if (!(is_fork_syscall(syscall_nr) && (retval == 0))) { int err; err = INTERNAL_SYSCALL(write, 3, logger_fd, &f, sizeof(f)); ASSERT(err == sizeof(f), &r, "write signal tag failed: %d\n", err); logger_sz += err; } /* don't allow signal in after_syscall. if signal happens * in it, the syscall handler may only write a part of log into * log file. when ckpt is made and resume, it will write the left, * makes the log file inconsistent. */ after_syscall(&r); INJ_SILENT("wrapped_syscall: %d over, retval=%d\n", syscall_nr, r.eax); /* in the assembly code, we have modify the 'eax'. */ /* check the logger sz */ INJ_SILENT("logger_sz = %d\n", logger_sz); /* don't switch when signal processing */ if ((logger_sz > injector_opts.logger_threshold) && (!IS_REENTER_SYSCALL())) { int err; /* we need to remake ckpt */ INJ_TRACE("make ckpt: eip=0x%x\n", r.eip); /* we still need to adjust esp: * when we come here, r.esp hold an 'ret' address for * coming 'ret'. */ ((struct syscall_regs*)(&r))->esp += 4; /* save fpustate */ save_i387(&fpustate_struct); make_checkpoint(ckpt_filename, (struct syscall_regs *)(&r), &fpustate_struct, NULL); ((struct syscall_regs*)(&r))->esp -= 4; /* truncate logger file */ err = INTERNAL_SYSCALL(ftruncate, 2, logger_fd, 0); ASSERT(err == 0, &r, "ftruncate failed: %d\n", err); /* reset logger_sz */ /* logger_sz have been reset in do_make_checkpoint */ /* logger_sz = 0; */ } EXIT_SYSCALL(); ENABLE_SIGNAL(); } else { /* this gate is useless in replay */ EXIT_SYSCALL(); ENABLE_SIGNAL(); INJ_SILENT("replay syscall, eax=%d\n", r.eax); uint32_t retval; retval = replay_syscall(&r); INJ_SILENT("syscall, eax=%d, replayed: %d\n", r.eax, retval); /* here we force to reset the eax */ (((volatile struct syscall_regs *)&r)->eax) = retval; } }