Task* Core::load_elf(unsigned int start, unsigned int size) { const char* phdr_types[] = { "NULL", "LOAD", "DYNAMIC", "INTERP", "NOTE", "SHLIB", "PHDR" }; Elf32_Ehdr* header = (Elf32_Ehdr*) start; if(header->e_type != ET_EXEC || header->e_machine != EM_386) { #ifdef _DEBUGGING_ELF_LOADER_ printf("load_elf: wrong machine or type\n"); #endif return NULL; } #ifdef _DEBUGGING_ELF_LOADER_ printf("load_elf: entry point is 0x%X\n", header->e_entry); #endif VirtualMemoryManager* vmm = new VirtualMemoryManager; Elf32_Phdr* pheader = (Elf32_Phdr*) (start + header->e_phoff); Elf32_Phdr* p; for(p = pheader; p < pheader + header->e_phnum; p++) { #ifdef _DEBUGGING_ELF_LOADER_ printf("load_elf: program header element type 0x%x\n", p->p_type); #endif if(p->p_type == PT_NULL) ; else if(p->p_type == PT_LOAD) { unsigned int pages = bytes_to_pages(p->p_memsz); if(p->p_filesz == 0) //FIXME: some bug at alloc_at??? continue; unsigned int phys = (start + p->p_offset) & 0xFFFFF000; unsigned int virt = p->p_vaddr & 0xFFFFF000; unsigned int count = pages; unsigned int flags = PAGE_PRESENT | PAGE_USER | (p->p_flags & PF_W ? PAGE_WRITABLE : 0); #ifdef _DEBUGGING_ELF_LOADER_ printf("load_elf: file 0x%X (0x%x bytes) -> virtual 0x%X (0x%x bytes)\n", p->p_offset, p->p_filesz, p->p_vaddr, p->p_memsz); printf("load_elf: flags = 0x%x, align = 0x%x\n", p->p_flags, p->p_align); printf("load_elf: mapping 0x%X to 0x%X: %i pages, %s\n", phys, virt, count, flags & PAGE_WRITABLE ? "writable" : "read only"); #endif vmm->alloc_at(phys, virt, count, flags, true, "ELF PT_LOAD segment"); } else { #ifdef _DEBUGGING_ELF_LOADER_ printf("load_elf: unknown section type\n"); #endif } } Task* task = hal->taskman->create_task(3, header->e_entry, 1, vmm); task->image = (void*) start; return task; }
unsigned int exec_syscall(Registers r) { void* image = hal->mm->alloc(bytes_to_pages(r.ebx)); memcpy(image, (void*) r.ecx, r.ebx); Task* task = core->load_executable((unsigned int) image, r.ebx, NULL); if(!task) return 0; else { task->tss->eflags |= 0x3000; task->wait_reason = wrNone; return task->index; } }
os_word round_bytes_to_page_size(os_word bytes) { return GC_PAGE_SIZE * bytes_to_pages(bytes); }