int elf_load (addrspace_t dest_as, char *elf_file) { int num_headers; int err; int i; /* Ensure that the ELF file looks sane. */ if (elf_checkFile(elf_file)){ return seL4_InvalidArgument; } num_headers = elf_getNumProgramHeaders(elf_file); for (i = 0; i < num_headers; i++) { char *source_addr; unsigned long flags, file_size, segment_size, vaddr; /* Skip non-loadable segments (such as debugging data). */ if (elf_getProgramHeaderType(elf_file, i) != PT_LOAD) continue; /* Fetch information about this segment. */ source_addr = elf_file + elf_getProgramHeaderOffset(elf_file, i); file_size = elf_getProgramHeaderFileSize(elf_file, i); segment_size = elf_getProgramHeaderMemorySize(elf_file, i); vaddr = elf_getProgramHeaderVaddr(elf_file, i); flags = elf_getProgramHeaderFlags(elf_file, i); /* Copy it across into the vspace. */ err = load_segment_directly_into_vspace(dest_as, source_addr, segment_size, file_size, vaddr, get_sel4_rights_from_elf(flags) & seL4_AllRights); if (err != 0) { return 1; } } return 0; }
int elf_load(seL4_RISCV_PageDirectory dest_as, char *elf_file) { int num_headers; int err; int i; /* Ensure that the ELF file looks sane. */ if (elf_checkFile(elf_file)){ return seL4_InvalidArgument; } num_headers = elf_getNumProgramHeaders(elf_file); for (i = 0; i < num_headers; i++) { char *source_addr; unsigned long flags, file_size, segment_size, vaddr; /* Skip non-loadable segments (such as debugging data). */ if (elf_getProgramHeaderType(elf_file, i) != PT_LOAD) continue; /* Fetch information about this segment. */ source_addr = elf_file + elf_getProgramHeaderOffset(elf_file, i); file_size = elf_getProgramHeaderFileSize(elf_file, i); segment_size = elf_getProgramHeaderMemorySize(elf_file, i); vaddr = elf_getProgramHeaderVaddr(elf_file, i); flags = elf_getProgramHeaderFlags(elf_file, i); /* Copy it across into the vspace. */ dprintf(1, " * Loading segment %08x-->%08x\n", (int)vaddr, (int)(vaddr + segment_size)); err = load_segment_into_vspace(dest_as, source_addr, segment_size, file_size, vaddr, get_sel4_rights_from_elf(flags) & seL4_AllRights); conditional_panic(err != 0, "Elf loading failed!\n"); } return 0; }
/* * Unpack an ELF file to the given physical address. */ static void unpack_elf_to_paddr(void *elf, paddr_t dest_paddr) { uint16_t i; uint64_t min_vaddr, max_vaddr; size_t image_size; word_t phys_virt_offset; /* Get size of the image. */ elf_getMemoryBounds(elf, 0, &min_vaddr, &max_vaddr); image_size = (size_t)(max_vaddr - min_vaddr); phys_virt_offset = dest_paddr - (paddr_t)min_vaddr; /* Zero out all memory in the region, as the ELF file may be sparse. */ memset((char *)dest_paddr, 0, image_size); /* Load each segment in the ELF file. */ for (i = 0; i < elf_getNumProgramHeaders(elf); i++) { vaddr_t dest_vaddr; size_t data_size, data_offset; /* Skip segments that are not marked as being loadable. */ if (elf_getProgramHeaderType(elf, i) != PT_LOAD) { continue; } /* Parse size/length headers. */ dest_vaddr = elf_getProgramHeaderVaddr(elf, i); data_size = elf_getProgramHeaderFileSize(elf, i); data_offset = elf_getProgramHeaderOffset(elf, i); /* Load data into memory. */ memcpy((char *)dest_vaddr + phys_virt_offset, (char *)elf + data_offset, data_size); } }
void elf_load(int pid, seL4_CPtr reply_cap, void *_args, int err) { if (TMP_DEBUG) printf("elf_load\n"); elf_load_args *args = (elf_load_args *) _args; if (err) { eprintf("Error caught in elf_load\n"); args->cb(pid, reply_cap, args->cb_args, err); free(args); return; } char *elf_file = args->elf_file; int curr_header = args->curr_header; //addr_space *as = proc_table[pid]; /* Ensure that the ELF file looks sane. */ if (elf_checkFile(elf_file)){ eprintf("Error caught in elf_load\n"); args->cb(pid, reply_cap, args->cb_args, -1); free(args); return; } int num_headers = elf_getNumProgramHeaders(elf_file); if (curr_header < num_headers) { char *source_addr; unsigned long flags, file_size, segment_size, vaddr; /* Skip non-loadable segments (such as debugging data). */ if (elf_getProgramHeaderType(elf_file, curr_header) != PT_LOAD) { args->curr_header++; elf_load(pid, reply_cap, args, 0); } else { /* Fetch information about this segment. */ source_addr = elf_file + elf_getProgramHeaderOffset(elf_file, curr_header); file_size = elf_getProgramHeaderFileSize(elf_file, curr_header); segment_size = elf_getProgramHeaderMemorySize(elf_file, curr_header); vaddr = elf_getProgramHeaderVaddr(elf_file, curr_header); flags = elf_getProgramHeaderFlags(elf_file, curr_header); /* Copy it across into the vspace. */ dprintf(1, " * Loading segment %08x-->%08x\n", (int)vaddr, (int)(vaddr + segment_size)); // Set up load segment arguments args->curr_header++; load_segment_args *segment_args = malloc(sizeof(load_segment_args)); if (segment_args == NULL) { eprintf("Error caught in elf_load\n"); args->cb(pid, reply_cap, args->cb_args, -1); free(args); return; } segment_args->src = source_addr; segment_args->dst = vaddr; segment_args->pos = 0; segment_args->segment_size = segment_size; segment_args->file_size = file_size; segment_args->permissions = get_sel4_rights_from_elf(flags) & seL4_AllRights; segment_args->cb = elf_load; segment_args->cb_args = args; load_segment_into_vspace(pid, reply_cap, segment_args, 0); } //conditional_panic(err != 0, "Elf loading failed!\n"); } else { // Do callback printf("Doing callback with pid :%d\n", pid); args->cb(pid, reply_cap, args->cb_args, 0); free(args); } if (TMP_DEBUG) printf("elf_load end\n"); }