1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-28 07:45:07 +00:00

Kernel: Implement basic module unloading :^)

Kernel modules can now be unloaded via a syscall. They get a chance to
run some code of course. Before deallocating them, we call their
"module_fini" symbol.
This commit is contained in:
Andreas Kling 2019-11-28 21:07:22 +01:00
parent 6b150c794a
commit a43b115a6c
6 changed files with 43 additions and 14 deletions

View file

@ -3418,8 +3418,6 @@ int Process::sys$module_load(const char* path, size_t path_length)
if (!elf_image->parse())
return -ENOEXEC;
ModuleInitPtr module_init = nullptr;
HashMap<String, u8*> section_storage_by_name;
auto module = make<Module>();
@ -3469,15 +3467,17 @@ int Process::sys$module_load(const char* path, size_t path_length)
elf_image->for_each_symbol([&](const ELFImage::Symbol& symbol) {
dbg() << " - " << symbol.type() << " '" << symbol.name() << "' @ " << (void*)symbol.value() << ", size=" << symbol.size();
if (!strcmp(symbol.name(), "module_init")) {
module_init = (ModuleInitPtr)(text_base + symbol.value());
module->module_init = (ModuleInitPtr)(text_base + symbol.value());
} else if (!strcmp(symbol.name(), "module_fini")) {
module->module_fini = (ModuleFiniPtr)(text_base + symbol.value());
}
return IterationDecision::Continue;
});
if (!module_init)
if (!module->module_init)
return -EINVAL;
module_init();
module->module_init();
auto name = module->name;
g_modules->set(name, move(module));
@ -3493,6 +3493,14 @@ int Process::sys$module_unload(const char* name, size_t name_length)
#endif
if (!validate_read(name, name_length))
return -EFAULT;
// FIXME: Implement this syscall!
auto it = g_modules->find(name);
if (it == g_modules->end())
return -ENOENT;
if (it->value->module_fini)
it->value->module_fini();
g_modules->remove(it);
return 0;
}