void c_main(int ac, char **av, char **env) { char *file_to_map = av[3]; char *file_to_unmap = av[2]; int how_to_map = 0; void *mapped; void *entry_point; unsigned long dummy; Elf64_Ehdr *elf_ehdr, *ldso_ehdr; struct saved_block *argvb, *envb, *elfauxvb; int trim_args; void *stack_bottom; unsigned long empty[32768]; empty[0] = 1; if (NULL == strstr(av[1], "dyn_unmap_run")) { file_to_map = av[1]; file_to_unmap = NULL; how_to_map = 1; trim_args = 1; } else { file_to_map = av[2]; file_to_unmap = av[0]; how_to_map = 0; trim_args = 2; } if (file_to_unmap) unmap(file_to_unmap); mapped = map_file(file_to_map, &dummy); elf_ehdr = (Elf64_Ehdr *)mapped; entry_point = load_elf(mapped, how_to_map, &elf_ehdr, &ldso_ehdr); linux_munmap(mapped, dummy); argvb = save_argv(ac - trim_args, &av[trim_args]); envb = save_argv(0, env); elfauxvb = save_elfauxv(env); stack_bottom = stack_setup(argvb, envb, elfauxvb, elf_ehdr, ldso_ehdr); SET_STACK(stack_bottom); JMP_ADDR(entry_point); }
void c_main(int ac, char **av, char **env) { char *file_to_map = av[1]; void *mapped; void *fptr; struct stat sb; Elf64_Ehdr *junk1 = NULL, *junk2 = NULL; /* print_string(1, "static_dyn_load_run\n"); */ if (0 > linux_stat(file_to_map, &sb)) { error_msg("stat() failed "); linux_exit(1); } mapped = linux_mmap(NULL, sb.st_size, 0x07, 0x22, -1, 0); /* print_address("File mapped in at", mapped); */ if (mapped == (void *)-1) { error_msg("mmap() failed "); linux_exit(1); } copy_in(file_to_map, mapped); fptr = load_elf(mapped, 1, &junk1, &junk2); /* print_address("Entry point at", fptr); */ linux_munmap(mapped, sb.st_size); /* print_address("Y setting stack to ", av - 1); */ SET_STACK(av - 1); JMP_ADDR(fptr); }
// ********************************************************************** // ********************************************************************** // dispatch curTask // static int dispatcher() { int result; // schedule task switch(tcb[curTask].state) { case S_NEW: { // new task printf("\nNew Task[%d] %s", curTask, tcb[curTask].name); tcb[curTask].state = S_RUNNING; // set task to run state // save kernel context for task SWAP's if (setjmp(k_context)) { superMode = TRUE; // supervisor mode break; // context switch to next task } // move to new task stack (leave room for return value/address) temp = (int*)tcb[curTask].stack + (STACK_SIZE-8); SET_STACK(temp); superMode = FALSE; // user mode // begin execution of new task, pass argc, argv result = (*tcb[curTask].task)(tcb[curTask].argc, tcb[curTask].argv); // task has completed if (result) printf("\nTask[%d] returned %d", curTask, result); else printf("\nTask[%d] returned %d", curTask, result); tcb[curTask].state = S_EXIT; // set task to exit state // return to kernal mode longjmp(k_context, 1); // return to kernel } case S_READY: { tcb[curTask].state = S_RUNNING; // set task to run } case S_RUNNING: { if (setjmp(k_context)) { // SWAP executed in task superMode = TRUE; // supervisor mode break; // return from task } if (signals()) break; longjmp(tcb[curTask].context, 3); // restore task context } case S_BLOCKED: { // ?? Could check here to unblock task break; } case S_EXIT: { if (curTask == 0) return -1; // if CLI, then quit scheduler // release resources and kill task sysKillTask(curTask); // kill current task break; } default: { printf("Unknown Task[%d] State", curTask); longjmp(reset_context, POWER_DOWN_ERROR); } } return 0; } // end dispatcher
void interpreter::call(const variant & func) { fake * fk = m_fk; const funcunion * f = m_fk->fm.get_func(func); if (UNLIKE(!f)) { FKERR("fkrun no func %s fail", vartostring(&func).c_str()); seterror(m_fk, efk_run_no_func_error, "fkrun no func %s fail", vartostring(&func).c_str()); m_isend = true; return; } // 常规函数 if (f->havefb) { const func_binary * fb = &f->fb; // 空函数处理 if (UNLIKE(!FUNC_BINARY_CMDSIZE(*fb))) { // 所有都完 if (ARRAY_EMPTY(m_stack_list)) { FKLOG("call stack empty end"); m_isend = true; } return; } // 压栈 if (UNLIKE(ARRAY_SIZE(m_stack_list) >= ARRAY_MAX_SIZE(m_stack_list))) { int newsize = ARRAY_MAX_SIZE(m_stack_list) + 1 + ARRAY_MAX_SIZE(m_stack_list) * m_fk->cfg.array_grow_speed / 100; ARRAY_GROW(m_stack_list, newsize, stack); } ARRAY_PUSH_BACK(m_stack_list); stack & s = ARRAY_BACK(m_stack_list); m_cur_stack = &s; STACK_INI(s, m_fk, fb); if (UNLIKE(FUNC_BINARY_MAX_STACK(*fb) > (int)ARRAY_MAX_SIZE(s.m_stack_variant_list))) { ARRAY_GROW(s.m_stack_variant_list, FUNC_BINARY_MAX_STACK(*fb), variant); } // 记录profile beginfuncprofile(); paramstack * ps = getps(m_fk); if (UNLIKE((int)ps->m_variant_list_num != FUNC_BINARY_PARAMNUM(*fb))) { FKERR("call func %s param not match", vartostring(&func).c_str()); seterror(m_fk, efk_run_param_error, "call func %s param not match", vartostring(&func).c_str()); m_isend = true; return; } assert(FUNC_BINARY_PARAMNUM(*fb) <= (int)ARRAY_MAX_SIZE(s.m_stack_variant_list)); // 分配栈空间 for (int i = 0; i < (int)FUNC_BINARY_PARAMNUM(*fb); i++) { SET_STACK(&(ps->m_variant_list[i]), s, i); FKLOG("call set %s to pos %d", (vartostring(&(ps->m_variant_list[i]))).c_str(), i); } ps->clear(); // 重置ret V_SET_NIL(&m_ret[0]); // 标记 FUNC_BINARY_USE(*fb)++; return; } // 记录profile uint32_t s = 0; if (m_fk->pf.isopen()) { s = fkgetmstick(); } // 绑定函数 if (f->haveff) { BIND_FUNC_CALL(f, this); FKLOG("call C func %s", vartostring(&func).c_str()); } // 内置函数 else if (f->havebif) { BUILDIN_FUNC_CALL(f, this); FKLOG("call buildin func %s", vartostring(&func).c_str()); } else { assert(0); FKERR("fkrun no inter func %s fail", vartostring(&func).c_str()); seterror(m_fk, efk_run_no_func_error, "fkrun no inter func %s fail", vartostring(&func).c_str()); m_isend = true; return; } // 返回值 paramstack * theps = getps(m_fk); bool err = false; USE(err); // 这种情况是直接跳过脚本调用了C函数 if (UNLIKE(ARRAY_EMPTY(m_stack_list))) { variant * cret; PS_POP_AND_GET(*theps, cret); m_isend = true; // 直接塞返回值 m_ret[0] = *cret; } // 否则塞到当前堆栈上 else { // 塞返回值 m_cur_stack = &ARRAY_BACK(m_stack_list); const func_binary & fb = *m_cur_stack->m_fb; for (int i = 0; i < m_cur_stack->m_retnum; i++) { variant * ret; GET_VARIANT(*m_cur_stack, fb, ret, m_cur_stack->m_retvpos[i]); variant * cret; PS_GET(*theps, cret, i); *ret = *cret; } } if (UNLIKE(err)) { m_isend = true; } if (m_fk->pf.isopen()) { bool err = false; const char * name = 0; V_GET_STRING(&func, name); m_fk->pf.add_func_sample(name, fkgetmstick() - s); } return; }