/** @brief dynamic linker ops */ static ke_handle process_ld(struct sysreq_process_ld *req) { ke_handle handle; xstring module_name; switch (req->function_type) { case SYSREQ_PROCESS_OPEN_EXE: { struct ko_exe *image; module_name = req->name; if (ke_validate_user_buffer(req->context, req->context_length, true) == false) goto ld_0_err; if (ke_validate_user_buffer(module_name, strlen(module_name), false) == false) goto ld_0_err; if (ke_validate_user_buffer(&req->map_base, sizeof(req->map_base), true) == false) goto ld_0_err; if ((image = kp_exe_open_by_name(KP_CURRENT(), module_name, &req->map_base)) == NULL) goto ld_0_err; if (kp_exe_copy_private(image, req->context, req->context_length) == false) goto ld_0_err1; /* Create handle for this image */ handle = ke_handle_create(image); if (handle == KE_INVALID_HANDLE) goto ld_0_err1; return handle; ld_0_err1: //TODO: close the object ld_0_err: return KE_INVALID_HANDLE; } /* Return the map base */ case SYSREQ_PROCESS_MAP_EXE_FILE: { struct ko_section *file_section; module_name = req->name; //printk("mapping exe file %s at user.\n", module_name); if (ke_validate_user_buffer(module_name, strlen(module_name), false) == false) goto map_0_err; file_section = map_file(KP_CURRENT(), module_name, KM_PROT_READ, &req->context_length); if (file_section == NULL) goto map_0_err; /* We are preparing to use this section for EXE file ananlyzing, so no real handle is needed */ //printk("map ok\n"); return (ke_handle)file_section->node.start; map_0_err: return 0; } /* Unamp file or module in current process space, req->handle is the module handle(if not by address of req->name) req->name is map base, return bool */ case SYSREQ_PROCESS_UNMAP_EXE_FILE: { if (req->name) return unmap_file(KP_CURRENT(), req->name); //TODO handle } break; /* Add a new exe object, return bool */ case SYSREQ_PROCESS_ENJECT_EXE: { void *ctx; int ctx_size; struct ko_section *file_section; ctx_size = req->context_length; ctx = req->context; module_name = req->name; if (ke_validate_user_buffer(ctx, ctx_size, false) == false) goto ld_3_err; if (ke_validate_user_buffer(module_name, strlen(module_name), false) == false) goto ld_3_err; if (ctx_size > kp_exe_get_context_size()) goto ld_3_err; if ((file_section = map_file(kp_get_file_process(), module_name, KM_PROT_READ, NULL)) == NULL) goto ld_3_err; if (kp_exe_create_from_file(module_name, file_section, ctx, NULL) == NULL) goto ld_3_err; return true; ld_3_err: return false; } default: break; } return 0; }
/** @brief dynamic linker ops */ static ke_handle process_ld(struct sysreq_process_ld * req) { ke_handle handle; xstring module_name; switch (req->function_type) { case SYSREQ_PROCESS_OPEN_EXE: { struct ko_exe *image; module_name = req->name; /* Validate the user buffer */ if (ke_validate_user_buffer(req->context, req->context_length, true) == false) goto ld_0_err; if (ke_validate_user_buffer(module_name, strlen(module_name), false) == false) goto ld_0_err; if (ke_validate_user_buffer(&req->map_base, sizeof(req->map_base), true) == false) goto ld_0_err; /* Open the image by name */ image = 0; if (!image) goto ld_0_err; if (kp_exe_copy_private(image, req->context, req->context_length) == false) goto ld_0_err1; /* Create handle for this image */ handle = ke_handle_create(image); if (handle == KE_INVALID_HANDLE) goto ld_0_err1; return handle; ld_0_err1: //TODO: close the object ld_0_err: return KE_INVALID_HANDLE; } /* Get file base and size */ case SYSREQ_PROCESS_MAP_EXE_FILE: { void *base; module_name = req->name; } /* 删除本地map的文件 */ case SYSREQ_PROCESS_UNMAP_EXE_FILE: { void *base = req->name; } /* Add a new exe object, return bool */ case SYSREQ_PROCESS_ENJECT_EXE: { struct ko_exe *image; void *ctx = req->context; int ctx_size = req->context_length; if (ke_validate_user_buffer(ctx, ctx_size, false) == false) goto ld_3_err; if (ke_validate_user_buffer(module_name, strlen(module_name), false) == false) goto ld_3_err; if (ctx_size > kp_exe_get_context_size()) goto ld_3_err; if (kp_exe_create_from_file(module_name, ctx) == NULL) goto ld_3_err; return true; ld_3_err: return false; } default: break; } }
/** @brief run startup process */ void ke_run_first_user_process(void *data, int size, char *cmdline) { char *first_space, first_exe_name[128] = {0}; struct ko_section *ks; void *entry_address; struct ko_exe *kee, *ke_tmp = kp_exe_create_temp(); first_space = strchr(cmdline, ' '); if (!first_space) goto err; if (first_space - cmdline >= sizeof(first_exe_name) - sizeof(xchar)) goto err; strncpy(first_exe_name, cmdline, first_space - cmdline); /* Kernel file process, because early we cannot copy lv2 table of driver */ kernel_file_process = kp_create(KP_CPL0_FAKE, "操作系统文件进程"); if (!kernel_file_process) goto err; printk("启动用户第一个可执行文件%x, size %d.\n", data, size); if (size == 0/*no file*/ || size == 1/*buffer error*/) goto err; if (elf_analyze(data, size, &entry_address, KO_EXE_TO_PRIVATE(ke_tmp)) == false) goto err; ks = ks_create(kp_get_file_process(), KS_TYPE_PRIVATE, 0, size, KM_PROT_READ|KM_PROT_WRITE); if (!ks) goto err; kee = kp_exe_create_from_file(first_exe_name, ks, KO_EXE_TO_PRIVATE(ke_tmp), entry_address); if (!kee) goto err; /* But this is a special one, we have to fill the data on it */ do { struct kt_thread_creating_context ctx = {0}; struct file_process_startup_para package; package.ks_start = ks->node.start; package.size = size; package.data = data; ctx.thread_entry = file_thread; ctx.flags = KT_CREATE_RUN; ctx.para = (unsigned long)&package; if (kt_create(kernel_file_process, &ctx) == NULL) goto err; /* Wait it to finish */ while (package.data) kt_schedule(); } while(0); /* OK, create the process */ if (kp_run_user(kee, ++first_space/*Real application*/) == false) goto err; return; err: printk("启动第一可执行文件失败。\n"); }
/** @brief dynamic linker ops */ static ke_handle process_ld(struct sysreq_process_ld * req) { ke_handle handle; xstring module_name; switch (req->function_type) { case SYSREQ_PROCESS_OPEN_EXE: { struct ko_exe *image; module_name = req->name; if (ke_validate_user_buffer(req->context, req->context_length, true) == false) goto ld_0_err; if (ke_validate_user_buffer(module_name, strlen(module_name), false) == false) goto ld_0_err; if (ke_validate_user_buffer(&req->map_base, sizeof(req->map_base), true) == false) goto ld_0_err; if ((image = kp_exe_open_by_name(KP_CURRENT(), module_name, &req->map_base)) == NULL) goto ld_0_err; if (kp_exe_copy_private(image, req->context, req->context_length) == false) goto ld_0_err1; /* Create handle for this image */ handle = ke_handle_create(image); if (handle == KE_INVALID_HANDLE) goto ld_0_err1; return handle; ld_0_err1: //TODO: close the object ld_0_err: return KE_INVALID_HANDLE; } /* Return the map base */ case SYSREQ_PROCESS_MAP_EXE_FILE: { struct ko_section *file_section; module_name = req->name; if (ke_validate_user_buffer(module_name, strlen(module_name), false) == false) goto map_0_err; file_section = map_file(KP_CURRENT(), module_name, KM_PROT_READ, &req->context_length); if (file_section == NULL) goto map_0_err; return (ke_handle)file_section->node.start; map_0_err: return 0; } /* 删除本地map的文件 */ case SYSREQ_PROCESS_UNMAP_EXE_FILE: { void *base = req->name; TRACE_UNIMPLEMENTED(""); } break; /* Add a new exe object, return bool */ case SYSREQ_PROCESS_ENJECT_EXE: { struct ko_exe *image; void *ctx; int ctx_size; unsigned long size; struct ko_section *file_section; ctx_size = req->context_length; ctx = req->context; module_name = req->name; if (ke_validate_user_buffer(ctx, ctx_size, false) == false) goto ld_3_err; if (ke_validate_user_buffer(module_name, strlen(module_name), false) == false) goto ld_3_err; if (ctx_size > kp_exe_get_context_size()) goto ld_3_err; if ((file_section = map_file(kp_get_file_process(), module_name, KM_PROT_READ, &size)) == NULL) goto ld_3_err; if (kp_exe_create_from_file(module_name, file_section, ctx, NULL) == NULL) goto ld_3_err; return true; ld_3_err: return false; } default: break; } return 0; }