mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +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:
parent
6b150c794a
commit
a43b115a6c
Notes:
sideshowbarker
2024-07-19 11:02:26 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/a43b115a6c9
6 changed files with 43 additions and 14 deletions
|
@ -4,10 +4,13 @@
|
|||
#include <AK/Vector.h>
|
||||
#include <Kernel/KBuffer.h>
|
||||
|
||||
typedef void* (*ModuleInitPtr)();
|
||||
typedef void* (*ModuleFiniPtr)();
|
||||
|
||||
struct Module {
|
||||
String name;
|
||||
Vector<KBuffer> sections;
|
||||
};
|
||||
|
||||
typedef void* (*ModuleInitPtr)();
|
||||
typedef void* (*ModuleFiniPtr)();
|
||||
ModuleInitPtr module_init { nullptr };
|
||||
ModuleFiniPtr module_fini { nullptr };
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include <Kernel/kstdio.h>
|
||||
|
||||
extern "C" void outside_func();
|
||||
|
||||
extern "C" void module_init()
|
||||
{
|
||||
kprintf("TestModule has booted!\n");
|
||||
|
@ -10,3 +8,8 @@ extern "C" void module_init()
|
|||
kprintf("i is now %d\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void module_fini()
|
||||
{
|
||||
kprintf("TestModule is being removed!\n");
|
||||
}
|
||||
|
|
|
@ -134,13 +134,13 @@ ln -s SoundPlayer mnt/bin/sp
|
|||
ln -s Help mnt/bin/help
|
||||
ln -s Browser mnt/bin/br
|
||||
ln -s HackStudio mnt/bin/hs
|
||||
ln -s modload mnt/bin/m
|
||||
echo "done"
|
||||
|
||||
mkdir -p mnt/boot/
|
||||
cp kernel mnt/boot/
|
||||
|
||||
cp TestModule.o mnt/
|
||||
mkdir -p mnt/mod/
|
||||
cp TestModule.o mnt/mod
|
||||
|
||||
# Run local sync script, if it exists
|
||||
if [ -f sync-local.sh ]; then
|
||||
|
|
|
@ -5,7 +5,7 @@ int main(int argc, char** argv)
|
|||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
const char* path = "/TestModule.o";
|
||||
const char* path = "/mod/TestModule.o";
|
||||
int rc = module_load(path, strlen(path));
|
||||
if (rc < 0) {
|
||||
perror("module_load");
|
||||
|
|
15
Userland/modunload.cpp
Normal file
15
Userland/modunload.cpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
#include <serenity.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
const char* name = "FIXME";
|
||||
int rc = module_unload(name, strlen(name));
|
||||
if (rc < 0) {
|
||||
perror("module_unload");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue