/** Parse an executable image in the kernel memory. * * If the image belongs to a program loader, it is registered as such, * (and *task is set to NULL). Otherwise a task is created from the * executable image. The task is returned in *task. * * @param[in] image_addr Address of an executable program image. * @param[in] name Name to set for the program's task. * @param[out] prg Buffer for storing program info. * If image_addr points to a loader image, * prg->task will be set to NULL and EOK * will be returned. * * @return EOK on success or negative error code. * */ int program_create_from_image(void *image_addr, char *name, program_t *prg) { as_t *as = as_create(0); if (!as) return ENOMEM; prg->loader_status = elf_load((elf_header_t *) image_addr, as, 0); if (prg->loader_status != EE_OK) { as_destroy(as); prg->task = NULL; prg->main_thread = NULL; if (prg->loader_status != EE_LOADER) return ENOTSUP; /* Register image as the program loader */ if (program_loader != NULL) return ELIMIT; program_loader = image_addr; printf("Program loader at %p\n", (void *) image_addr); return EOK; } return program_create(as, ((elf_header_t *) image_addr)->e_entry, name, prg); }
/** Create a task from the program loader image. * * @param prg Buffer for storing program info. * @param name Name to set for the program's task. * * @return EOK on success or negative error code. * */ int program_create_loader(program_t *prg, char *name) { as_t *as = as_create(0); if (!as) return ENOMEM; void *loader = program_loader; if (!loader) { as_destroy(as); printf("Cannot spawn loader as none was registered\n"); return ENOENT; } prg->loader_status = elf_load((elf_header_t *) program_loader, as, ELD_F_LOADER); if (prg->loader_status != EE_OK) { as_destroy(as); printf("Cannot spawn loader (%s)\n", elf_error(prg->loader_status)); return ENOENT; } return program_create(as, ((elf_header_t *) program_loader)->e_entry, name, prg); }
ast_t* ast_token(token_t* t) { ast_t* ast = POOL_ALLOC(ast_t); memset(ast, 0, sizeof(ast_t)); ast->t = t; switch(token_get_id(t)) { case TK_PROGRAM: ast->data = program_create(); break; default: break; } return ast; }