diff --git a/src/tasking/syscalls.c b/src/tasking/syscalls.c index a5acc8f..c102b8c 100644 --- a/src/tasking/syscalls.c +++ b/src/tasking/syscalls.c @@ -331,68 +331,68 @@ extern void execve_return(TrapFrame *tf); /** * this might be a not really good implementation as it only supports * up to EXECVE_MAX_ARGUMENT_SIZE characters in each argument or environment - * string and for some reason I was unable to use malloc for kernel_argv and - * kernel_envp + * string */ int sys_execve(TrapFrame *tf) { const char* filename = (const char*)tf->ebx; - char **argv = (char**)tf->ecx; char **envp = (char**)tf->edx; int argc = 0; + while(argv[argc] != NULL) argc++; + int envc = 0; + while(envp[envc] != NULL) envc++; - while(argv[argc] != NULL) - { - argc++; - } - while(envp[envc] != NULL) - { - envc++; - } + char** kernel_argv = malloc((argc + 1) * sizeof(char*)); + if (!kernel_argv) return -1; - //TODO: check why was there a triple fault when I tried using malloc - char kernel_argv[argc][EXECVE_MAX_ARGUMENT_SIZE]; - char kernel_envp[envc][EXECVE_MAX_ARGUMENT_SIZE]; - - for(int i = 0; i < argc; i++) - { + for(int i = 0; i < argc; i++) { + kernel_argv[i] = malloc(EXECVE_MAX_ARGUMENT_SIZE); strcpy(kernel_argv[i], argv[i]); } + kernel_argv[argc] = NULL; - for(int i = 0; i < envc; i++) - { + char** kernel_envp = malloc((envc + 1) * sizeof(char*)); + if (!kernel_envp) return -1; // TODO: cleanup kernel_argv + + for(int i = 0; i < envc; i++) { + kernel_envp[i] = malloc(EXECVE_MAX_ARGUMENT_SIZE); strcpy(kernel_envp[i], envp[i]); } + kernel_envp[envc] = NULL; uint8_t* file_buffer; int err = vfs_read_file_by_path(filename, &file_buffer); if (err != 0) { - debug_log("execve: failed to read file '%s'\n", filename); + // TODO: Free kernel_argv/envp + debug_log("execve: failed to read file\n"); return -1; } Elf32_Ehdr *elf_header = (Elf32_Ehdr*)file_buffer; if (memcmp(elf_header->e_ident, "\x7F" "ELF", 4) != 0) { - debug_log("execve: '%s' is not a valid ELF file\n", filename); - free(file_buffer); + // TODO: Free resources return -1; } uint32_t* new_page_dir = create_page_dir(); - if (!new_page_dir) { - free(file_buffer); - return -1; - } - uint32_t new_page_dir_phys = (uint32_t)get_physaddr((void*)new_page_dir); - uint32_t* old_page_dir_to_free = current->pagedir; + if (!new_page_dir) return -1; - set_page_dir(new_page_dir_phys); - current->pagedir = new_page_dir; + uint32_t new_page_dir_phys = (uint32_t)get_physaddr((void*)new_page_dir); + + void* process_phys = get_physaddr(current); + map_page_in_directory(new_page_dir, process_phys, current, PAGE_PRESENT | PAGE_RW); void* kstack_phys = get_physaddr(current->kstack); - map_page(kstack_phys, current->kstack, PAGE_PRESENT | PAGE_RW); + map_page_in_directory(new_page_dir, kstack_phys, current->kstack, PAGE_PRESENT | PAGE_RW); + + void* argv_phys = get_physaddr(kernel_argv); + map_page_in_directory(new_page_dir, argv_phys, kernel_argv, PAGE_PRESENT | PAGE_RW); + + uint32_t* old_page_dir_to_free = current->pagedir; + set_page_dir(new_page_dir_phys); + current->pagedir = new_page_dir; uint32_t highest_vaddr = 0; for (int i = 0; i < elf_header->e_phnum; i++) { @@ -400,7 +400,6 @@ int sys_execve(TrapFrame *tf) { if (p_header->p_type == PT_LOAD) { uint32_t start_addr = p_header->p_vaddr; uint32_t end_addr = start_addr + p_header->p_memsz; - uint32_t start_page = start_addr & ~0xFFF; uint32_t end_page = (end_addr - 1) & ~0xFFF; @@ -413,9 +412,7 @@ int sys_execve(TrapFrame *tf) { if (p_header->p_memsz > p_header->p_filesz) { memset((void*)(p_header->p_vaddr + p_header->p_filesz), 0, p_header->p_memsz - p_header->p_filesz); } - if (p_header->p_vaddr + p_header->p_memsz > highest_vaddr) { - highest_vaddr = p_header->p_vaddr + p_header->p_memsz; - } + if (end_addr > highest_vaddr) highest_vaddr = end_addr; } } @@ -426,7 +423,6 @@ int sys_execve(TrapFrame *tf) { uint32_t user_esp = USER_STACK_TOP; - //push environment strings uint32_t envp_pointers[envc + 1]; for (int i = envc - 1; i >= 0; i--) { size_t len = strlen(kernel_envp[i]) + 1; @@ -434,9 +430,8 @@ int sys_execve(TrapFrame *tf) { memcpy((void*)user_esp, kernel_envp[i], len); envp_pointers[i] = user_esp; } - envp_pointers[envc] = 0;//null terminator - - //push argument strings + envp_pointers[envc] = 0; + uint32_t argv_pointers[argc + 1]; for (int i = argc - 1; i >= 0; i--) { size_t len = strlen(kernel_argv[i]) + 1; @@ -444,22 +439,25 @@ int sys_execve(TrapFrame *tf) { memcpy((void*)user_esp, kernel_argv[i], len); argv_pointers[i] = user_esp; } - argv_pointers[argc] = 0;//null terminator + argv_pointers[argc] = 0; - //push envp pointers user_esp -= (envc + 1) * sizeof(uint32_t); memcpy((void*)user_esp, envp_pointers, (envc + 1) * sizeof(uint32_t)); - //push argv pointers user_esp -= (argc + 1) * sizeof(uint32_t); memcpy((void*)user_esp, argv_pointers, (argc + 1) * sizeof(uint32_t)); - //push argc user_esp -= sizeof(uint32_t); *((uint32_t*)user_esp) = argc; current->brk = (void*)(DivRoundUp(highest_vaddr, PAGE_SIZE) * PAGE_SIZE); + free(file_buffer); + for(int i=0; igs = SEG_UDATA | DPL_USER; @@ -475,7 +473,6 @@ int sys_execve(TrapFrame *tf) { tf->usermode_ss = SEG_UDATA | DPL_USER; execve_return(tf); - return 0; }