spawn: Parse the ELF
This commit is contained in:
parent
6b911752f0
commit
07a20776de
@ -583,6 +583,7 @@ errors spawn SPAWN_ERR_ {
|
|||||||
failure VSPACE_INIT "Failure in spawn_vspace_init",
|
failure VSPACE_INIT "Failure in spawn_vspace_init",
|
||||||
failure SETUP_DISPATCHER "Failure in spawn_setup_dispatcher",
|
failure SETUP_DISPATCHER "Failure in spawn_setup_dispatcher",
|
||||||
failure ELF_MAP "Failure in spawn_elf_map",
|
failure ELF_MAP "Failure in spawn_elf_map",
|
||||||
|
failure ELF_LOAD "Failure in elf_load",
|
||||||
|
|
||||||
failure SET_CAPS "Failure in set_special_caps",
|
failure SET_CAPS "Failure in set_special_caps",
|
||||||
failure MONEP_SLOT_ALLOC "Failure allocating a slot for monitor EP",
|
failure MONEP_SLOT_ALLOC "Failure allocating a slot for monitor EP",
|
||||||
|
|||||||
@ -86,6 +86,43 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
|
|||||||
return LIB_ERR_NOT_IMPLEMENTED;
|
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.
|
* 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);
|
struct mem_region *module = multiboot_find_module(bi, binary_name);
|
||||||
if (module == NULL) return SPAWN_ERR_FIND_MODULE;
|
if (module == NULL) return SPAWN_ERR_FIND_MODULE;
|
||||||
|
|
||||||
|
// - Get the frame of the ELF
|
||||||
struct capref child_frame = {
|
struct capref child_frame = {
|
||||||
.cnode = cnode_module,
|
.cnode = cnode_module,
|
||||||
.slot = module->mrmod_slot,
|
.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);
|
err = cap_direct_identify(child_frame, &c);
|
||||||
if (err_is_fail(err)) return err;
|
if (err_is_fail(err)) return err;
|
||||||
gensize_t frame_size = get_size(&c);
|
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;
|
char *module_data;
|
||||||
err = paging_map_frame_attr(
|
err = paging_map_frame_attr(
|
||||||
get_current_paging_state(), (void **)&module_data,
|
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);
|
if (err_is_fail(err)) return err_push(err, SPAWN_ERR_MAP_MODULE);
|
||||||
|
|
||||||
debug_printf("SPAWN: mapped %s, magic: %"PRIx8" %c%c%c\n",
|
debug_printf("SPAWN: mapped %s, size: %"PRIx64", magic: %"PRIx8" %c%c%c\n",
|
||||||
binary_name, module_data[0], module_data[1], module_data[2], module_data[3]);
|
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
|
// - Fill in argc/argv from the multiboot command line
|
||||||
// - Call spawn_load_argv
|
// - Call spawn_load_argv
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user