From 51f4c0c75063c00df376e2bd1ec18290cba4d43e Mon Sep 17 00:00:00 2001 From: Bananymous Date: Sun, 4 Jun 2023 01:24:11 +0300 Subject: [PATCH] Kernel: make load_elf() its own function --- kernel/include/kernel/Process.h | 4 +- kernel/kernel/Process.cpp | 84 ++++++++++++++++++--------------- 2 files changed, 50 insertions(+), 38 deletions(-) diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index b46243d9c..6786cf066 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -14,6 +14,8 @@ #include +namespace LibELF { class ELF; } + namespace Kernel { @@ -86,7 +88,7 @@ namespace Kernel static Process* create_process(); static void register_process(Process*); - BAN::ErrorOr cleanup_and_load_elf(BAN::StringView); + void load_elf(LibELF::ELF&); BAN::ErrorOr absolute_path_of(BAN::StringView) const; diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 2a88dc116..e331f943e 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -46,15 +46,19 @@ namespace Kernel BAN::ErrorOr Process::create_userspace(BAN::StringView path) { + auto* elf = TRY(LibELF::ELF::load_from_file(path)); + if (!elf->is_native()) + { + derrorln("ELF has invalid architecture"); + delete elf; + return BAN::Error::from_errno(EINVAL); + } + auto* process = create_process(); MUST(process->m_working_directory.push_back('/')); process->m_page_table = MUST(PageTable::create_userspace()); - if (auto res = process->cleanup_and_load_elf(path); res.is_error()) - { - delete process; - return res.error(); - } + process->load_elf(*elf); char** argv = nullptr; { @@ -68,6 +72,9 @@ namespace Kernel process->m_userspace_entry.argc = 1; process->m_userspace_entry.argv = argv; + process->m_userspace_entry.entry = elf->file_header_native().e_entry; + + delete elf; auto* thread = MUST(Thread::create_userspace(process)); process->add_thread(thread); @@ -198,9 +205,30 @@ namespace Kernel if (str_envp.emplace_back(*envp++).is_error()) return BAN::Error::from_errno(ENOMEM); + auto* elf = TRY(LibELF::ELF::load_from_file(path)); + if (!elf->is_native()) + { + derrorln("ELF has invalid architecture"); + delete elf; + return BAN::Error::from_errno(EINVAL); + } + LockGuard lock_guard(m_lock); - MUST(cleanup_and_load_elf(path)); + m_fixed_width_allocators.clear(); + m_general_allocator.clear(); + + for (auto* range : m_mapped_ranges) + delete range; + m_mapped_ranges.clear(); + + m_open_files.clear(); + + load_elf(*elf); + + m_userspace_entry.entry = elf->file_header_native().e_entry; + + delete elf; ASSERT(m_threads.size() == 1); ASSERT(&Process::current() == this); @@ -231,33 +259,14 @@ namespace Kernel } - BAN::ErrorOr Process::cleanup_and_load_elf(BAN::StringView path) + void Process::load_elf(LibELF::ELF& elf) { - auto* elf = TRY(LibELF::ELF::load_from_file(path)); - if (!elf->is_native()) - { - derrorln("ELF has invalid architecture"); - return BAN::Error::from_errno(EINVAL); - } + ASSERT(elf.is_native()); - for (auto* allocator : m_fixed_width_allocators) - delete allocator; - m_fixed_width_allocators.clear(); - - if (m_general_allocator) - delete m_general_allocator; - m_general_allocator = nullptr; - - for (auto* range : m_mapped_ranges) - delete range; - m_mapped_ranges.clear(); - - m_open_files.clear(); - - auto& elf_file_header = elf->file_header_native(); + auto& elf_file_header = elf.file_header_native(); for (size_t i = 0; i < elf_file_header.e_phnum; i++) { - auto& elf_program_header = elf->program_header_native(i); + auto& elf_program_header = elf.program_header_native(i); switch (elf_program_header.p_type) { @@ -265,7 +274,14 @@ namespace Kernel break; case LibELF::PT_LOAD: { - ASSERT(page_table().is_range_free(elf_program_header.p_vaddr, elf_program_header.p_memsz)); + if (!page_table().is_range_free(elf_program_header.p_vaddr, elf_program_header.p_memsz)) + { + page_table().debug_dump(); + Kernel::panic("vaddr {8H}-{8H} not free", + elf_program_header.p_vaddr, + elf_program_header.p_vaddr + elf_program_header.p_memsz + ); + } uint8_t flags = PageTable::Flags::UserSupervisor | PageTable::Flags::Present; if (elf_program_header.p_flags & LibELF::PF_W) flags |= PageTable::Flags::ReadWrite; @@ -277,7 +293,7 @@ namespace Kernel { PageTableScope _(page_table()); - memcpy((void*)elf_program_header.p_vaddr, elf->data() + elf_program_header.p_offset, elf_program_header.p_filesz); + memcpy((void*)elf_program_header.p_vaddr, elf.data() + elf_program_header.p_offset, elf_program_header.p_filesz); memset((void*)(elf_program_header.p_vaddr + elf_program_header.p_filesz), 0, elf_program_header.p_memsz - elf_program_header.p_filesz); } break; @@ -286,12 +302,6 @@ namespace Kernel ASSERT_NOT_REACHED(); } } - - m_userspace_entry.entry = elf_file_header.e_entry; - - delete elf; - - return {}; } BAN::ErrorOr Process::open(BAN::StringView path, int flags)