mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 11:17:43 +00:00
Kernel: Load ELF executable pages lazily when possible.
This currently only works for "normal" processes created by fork(). It does not work for create_user_process() processes spawned by the kernel, as those are a bit special during construction.
This commit is contained in:
parent
baab9f4402
commit
75207ddffd
1 changed files with 8 additions and 14 deletions
|
@ -322,13 +322,15 @@ int Process::do_exec(String path, Vector<String> arguments, Vector<String> envir
|
||||||
#endif
|
#endif
|
||||||
RetainPtr<Region> region = allocate_region_with_vmo(LinearAddress(), descriptor->metadata().size, vmo.copy_ref(), 0, "executable", true, false);
|
RetainPtr<Region> region = allocate_region_with_vmo(LinearAddress(), descriptor->metadata().size, vmo.copy_ref(), 0, "executable", true, false);
|
||||||
|
|
||||||
// FIXME: Should we consider doing on-demand paging here? Is it actually useful?
|
if (this != ¤t->process()) {
|
||||||
bool success = region->page_in();
|
// FIXME: Don't force-load the entire executable at once, let the on-demand pager take care of it.
|
||||||
|
bool success = region->page_in();
|
||||||
ASSERT(success);
|
ASSERT(success);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
// Okay, here comes the sleight of hand, pay close attention..
|
// Okay, here comes the sleight of hand, pay close attention..
|
||||||
auto old_regions = move(m_regions);
|
auto old_regions = move(m_regions);
|
||||||
|
m_regions.append(*region);
|
||||||
ELFLoader loader(region->laddr().as_ptr());
|
ELFLoader loader(region->laddr().as_ptr());
|
||||||
loader.map_section_hook = [&] (LinearAddress laddr, size_t size, size_t alignment, size_t offset_in_image, bool is_readable, bool is_writable, const String& name) {
|
loader.map_section_hook = [&] (LinearAddress laddr, size_t size, size_t alignment, size_t offset_in_image, bool is_readable, bool is_writable, const String& name) {
|
||||||
ASSERT(size);
|
ASSERT(size);
|
||||||
|
@ -347,25 +349,17 @@ int Process::do_exec(String path, Vector<String> arguments, Vector<String> envir
|
||||||
return laddr.as_ptr();
|
return laddr.as_ptr();
|
||||||
};
|
};
|
||||||
bool success = loader.load();
|
bool success = loader.load();
|
||||||
if (!success) {
|
if (!success || !loader.entry().get()) {
|
||||||
m_page_directory = move(old_page_directory);
|
m_page_directory = move(old_page_directory);
|
||||||
// FIXME: RAII this somehow instead.
|
// FIXME: RAII this somehow instead.
|
||||||
ASSERT(¤t->process() == this);
|
ASSERT(¤t->process() == this);
|
||||||
MM.enter_process_paging_scope(*this);
|
MM.enter_process_paging_scope(*this);
|
||||||
m_regions = move(old_regions);
|
m_regions = move(old_regions);
|
||||||
kprintf("sys$execve: Failure loading %s\n", path.characters());
|
kprintf("do_exec: Failure loading %s\n", path.characters());
|
||||||
return -ENOEXEC;
|
return -ENOEXEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry_eip = loader.entry().get();
|
entry_eip = loader.entry().get();
|
||||||
if (!entry_eip) {
|
|
||||||
m_page_directory = move(old_page_directory);
|
|
||||||
// FIXME: RAII this somehow instead.
|
|
||||||
ASSERT(¤t->process() == this);
|
|
||||||
MM.enter_process_paging_scope(*this);
|
|
||||||
m_regions = move(old_regions);
|
|
||||||
return -ENOEXEC;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kfree(current->m_kernel_stack_for_signal_handler);
|
kfree(current->m_kernel_stack_for_signal_handler);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue