spawn: Parse the ELF

This commit is contained in:
Jan Schär 2022-03-22 21:18:36 +01:00
parent 6b911752f0
commit 07a20776de
2 changed files with 49 additions and 3 deletions

View File

@ -583,6 +583,7 @@ errors spawn SPAWN_ERR_ {
failure VSPACE_INIT "Failure in spawn_vspace_init",
failure SETUP_DISPATCHER "Failure in spawn_setup_dispatcher",
failure ELF_MAP "Failure in spawn_elf_map",
failure ELF_LOAD "Failure in elf_load",
failure SET_CAPS "Failure in set_special_caps",
failure MONEP_SLOT_ALLOC "Failure allocating a slot for monitor EP",

View File

@ -86,6 +86,43 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
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.
@ -108,6 +145,7 @@ errval_t spawn_load_by_name(char *binary_name, struct spawninfo * si,
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,
@ -117,8 +155,9 @@ errval_t spawn_load_by_name(char *binary_name, struct spawninfo * si,
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->mr_bytes) return SPAWN_ERR_MODULE_FRAME_TOO_SMALL;
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,
@ -126,8 +165,14 @@ errval_t spawn_load_by_name(char *binary_name, struct spawninfo * si,
);
if (err_is_fail(err)) return err_push(err, SPAWN_ERR_MAP_MODULE);
debug_printf("SPAWN: mapped %s, magic: %"PRIx8" %c%c%c\n",
binary_name, module_data[0], module_data[1], module_data[2], module_data[3]);
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