#include #include #include #include #include #include #include #include #include #include #include #include extern struct bootinfo *bi; extern coreid_t my_core_id; /** * \brief Set the base address of the .got (Global Offset Table) section of the ELF binary * * \param arch_load_info This must be the base address of the .got section (local to the * child's VSpace). Must not be NULL. * \param handle The handle for the new dispatcher that is to be spawned. Must not be NULL. * \param enabled_area The "resume enabled" register set. Must not be NULL. * \param disabled_area The "resume disabled" register set. Must not be NULL. */ __attribute__((__used__)) static void armv8_set_registers(void *arch_load_info, dispatcher_handle_t handle, arch_registers_state_t *enabled_area, arch_registers_state_t *disabled_area) { assert(arch_load_info != NULL); uintptr_t got_base = (uintptr_t) arch_load_info; struct dispatcher_shared_aarch64 * disp_arm = get_dispatcher_shared_aarch64(handle); disp_arm->got_base = got_base; enabled_area->regs[REG_OFFSET(PIC_REGISTER)] = got_base; disabled_area->regs[REG_OFFSET(PIC_REGISTER)] = got_base; } /** * TODO(M2): Implement this function. * \brief Spawn a new dispatcher called 'argv[0]' with 'argc' arguments. * * This function spawns a new dispatcher running the ELF binary called * 'argv[0]' with 'argc' - 1 additional arguments. It fills out 'si' * and 'pid'. * * \param argc The number of command line arguments. Must be > 0. * \param argv An array storing 'argc' command line arguments. * \param si A pointer to the spawninfo struct representing * the child. It will be filled out by this function. Must not be NULL. * \param pid A pointer to a domainid_t variable that will be * assigned to by this function. Must not be NULL. * \return Either SYS_ERR_OK if no error occured or an error * indicating what went wrong otherwise. */ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si, domainid_t *pid) { // TODO: Implement me // - Initialize the spawn_info struct // - Get the module from the multiboot image // and map it (take a look at multiboot.c) // - Setup the child's cspace // - Setup the child's vspace // - Load the ELF binary // - Setup the dispatcher // - Setup the environment // - Make the new dispatcher runnable return LIB_ERR_NOT_IMPLEMENTED; } struct allocate_state { // TODO: add fields }; static errval_t elf_allocate( void *state, genvaddr_t base, size_t size, uint32_t flags, void **ret ) { errval_t err; // struct allocate_state *st = state; // Allocate a frame struct capref frame; err = slot_alloc(&frame); if (err_is_fail(err)) return err_push(err, LIB_ERR_SLOT_ALLOC); size_t alloc_bytes; err = frame_create(frame, size, &alloc_bytes); if (err_is_fail(err)) { slot_free(frame); return err_push(err, LIB_ERR_FRAME_ALLOC); } // Map into current address space err = paging_map_frame_attr( get_current_paging_state(), ret, alloc_bytes, frame, VREGION_FLAGS_READ_WRITE ); if (err_is_fail(err)) return err; // TODO: Map into child address space return SYS_ERR_OK; } /** * TODO(M2): Implement this function. * \brief Spawn a new dispatcher executing 'binary_name' * * \param binary_name The name of the binary. * \param si A pointer to a spawninfo struct that will be * filled out by spawn_load_by_name. Must not be NULL. * \param pid A pointer to a domainid_t that will be * filled out by spawn_load_by_name. Must not be NULL. * * \return Either SYS_ERR_OK if no error occured or an error * indicating what went wrong otherwise. */ errval_t spawn_load_by_name(char *binary_name, struct spawninfo * si, domainid_t *pid) { errval_t err; // - Get the mem_region from the multiboot image struct mem_region *module = multiboot_find_module(bi, binary_name); if (module == NULL) return SPAWN_ERR_FIND_MODULE; // - Get the frame of the ELF struct capref child_frame = { .cnode = cnode_module, .slot = module->mrmod_slot, }; struct capability c; err = cap_direct_identify(child_frame, &c); if (err_is_fail(err)) return err; gensize_t frame_size = get_size(&c); if (frame_size < module->mrmod_size) return SPAWN_ERR_MODULE_FRAME_TOO_SMALL; // - Map the ELF into the current addess space char *module_data; err = paging_map_frame_attr( get_current_paging_state(), (void **)&module_data, frame_size, child_frame, VREGION_FLAGS_READ ); if (err_is_fail(err)) return err_push(err, SPAWN_ERR_MAP_MODULE); debug_printf("SPAWN: mapped %s, size: %"PRIx64", magic: %"PRIx8" %c%c%c\n", binary_name, module->mrmod_size, module_data[0], module_data[1], module_data[2], module_data[3]); // - Parse the ELF struct allocate_state st = {}; genvaddr_t entry; err = elf_load(EM_AARCH64, elf_allocate, &st, (lvaddr_t)module_data, module->mrmod_size, &entry); if (err_is_fail(err)) return err_push(err, SPAWN_ERR_ELF_LOAD); // - Fill in argc/argv from the multiboot command line // - Call spawn_load_argv return LIB_ERR_NOT_IMPLEMENTED; }