mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-24 21:45:20 +00:00
Kernel+Userland: Remove loadable kernel moduless
These interfaces are broken for about 9 months, maybe longer than that. At this point, this is just a dead code nobody tests or tries to use, so let's remove it instead of keeping a stale code just for the sake of keeping it and hoping someone will fix it. To better justify this, I read that OpenBSD removed loadable kernel modules in 5.7 release (2014), mainly for the same reason we do - nobody used it so they had no good reason to maintain it. Still, OpenBSD had LKMs being effectively working, which is not the current state in our project for a long time. An arguably better approach to minimize the Kernel image size is to allow dropping drivers and features while compiling a new image.
This commit is contained in:
parent
b92871f7ef
commit
04ba31b8c5
Notes:
sideshowbarker
2024-07-18 04:15:47 +09:00
Author: https://github.com/supercomputer7 Commit: https://github.com/SerenityOS/serenity/commit/04ba31b8c5e Pull-request: https://github.com/SerenityOS/serenity/pull/9965
19 changed files with 0 additions and 530 deletions
|
@ -1,35 +0,0 @@
|
|||
## Name
|
||||
|
||||
module\_load - load a kernel module
|
||||
|
||||
## Synopsis
|
||||
|
||||
```**c++
|
||||
#include <serenity.h>
|
||||
|
||||
int module_load(const char* path, size_t path_length);
|
||||
```
|
||||
|
||||
## Description
|
||||
|
||||
`module_load()` will load a kernel module from an ELF object file given its
|
||||
path in the filesystem.
|
||||
|
||||
## Return value
|
||||
|
||||
If the module is successfully loaded, `module_load()` returns 0. Otherwise, it
|
||||
returns -1 and sets `errno` to describe the error.
|
||||
|
||||
## Errors
|
||||
|
||||
* `EPERM`: The calling process does not have superuser permissions.
|
||||
* `EFAULT`: `path` pointed to memory that was not accessible for the caller.
|
||||
* `ENOEXEC`: The specified file could not be parsed as an ELF object.
|
||||
* `EINVAL`: One or more symbols referred to by the module could not be resolved, or the module had no `.text` section, or didn't export a `module_init` function.
|
||||
* `EEXIST`: A module with the same name was already loaded.
|
||||
|
||||
## See also
|
||||
|
||||
* [`module_unload`(2)](module_unload.md)
|
||||
* [`modload`(8)](../man8/modload.md)
|
||||
* [`kernel_modules`(7)](../man7/kernel_modules.md)
|
|
@ -1,32 +0,0 @@
|
|||
## Name
|
||||
|
||||
module\_unload - unload a kernel module
|
||||
|
||||
## Synopsis
|
||||
|
||||
```**c++
|
||||
#include <serenity.h>
|
||||
|
||||
int module_unload(const char* name, size_t name_length);
|
||||
```
|
||||
|
||||
## Description
|
||||
|
||||
`module_unload()` will unload a kernel module by name.
|
||||
|
||||
## Return value
|
||||
|
||||
If the module is successfully unloaded, `module_unload()` returns 0.
|
||||
Otherwise, it returns -1 and sets `errno` to describe the error.
|
||||
|
||||
## Errors
|
||||
|
||||
* `EPERM`: The calling process does not have superuser permissions.
|
||||
* `EFAULT`: `path` pointed to memory that was not accessible for the caller.
|
||||
* `ENOENT`: There was no module loaded with the specified name.
|
||||
|
||||
## See also
|
||||
|
||||
* [`module_load`(2)](module_load.md)
|
||||
* [`modunload`(8)](../man8/modunload.md)
|
||||
* [`kernel_modules`(7)](../man7/kernel_modules.md)
|
|
@ -1,65 +0,0 @@
|
|||
## Name
|
||||
|
||||
Kernel Modules - runtime code loading for the kernel
|
||||
|
||||
## Description
|
||||
|
||||
Serenity's kernel supports loading modules at runtime. This functionality can
|
||||
be used to implement optional features (e.g. drivers), and speed up your
|
||||
development cycle.
|
||||
|
||||
## Module format
|
||||
|
||||
A kernel module is a regular ELF object file which must export several
|
||||
symbols. Any symbols it refers to will be resolved when it is loaded.
|
||||
|
||||
### `module_name`
|
||||
|
||||
This should be a string like `const char module_name[]` containing the name of
|
||||
the module. This is used to give the module a name in any informational
|
||||
contexts, but also to ensure that the module is not loaded twice by accident,
|
||||
and also used as a reference to unload the module later.
|
||||
|
||||
### `module_init`
|
||||
|
||||
This should be a function with the following signature: `void module_init()`.
|
||||
It will be called when the module is loaded.
|
||||
|
||||
### `module_fini`
|
||||
|
||||
This is optional, but if defined it should be a function with the following
|
||||
signature: `void module_fini()`. It will be called when the module is
|
||||
unloaded.
|
||||
|
||||
## Example:
|
||||
|
||||
```c++
|
||||
#include <Kernel/kstdio.h>
|
||||
#include <Kernel/Process.h>
|
||||
|
||||
extern "C" const char module_name[] = "ExampleModule";
|
||||
|
||||
extern "C" void module_init()
|
||||
{
|
||||
kprintf("ExampleModule has booted!\n");
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
kprintf("i is now %d\n", i);
|
||||
}
|
||||
|
||||
kprintf("current pid: %d\n", current->process().sys$getpid());
|
||||
kprintf("current process name: %s\n", current->process().name().characters());
|
||||
}
|
||||
|
||||
extern "C" void module_fini()
|
||||
{
|
||||
kprintf("ExampleModule is being removed!\n");
|
||||
}
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
* [`modload`(8)](../man8/modload.md)
|
||||
* [`modunload`(8)](../man8/modunload.md)
|
||||
* [`module_load`(2)](../man2/module_load.md)
|
||||
* [`module_unload`(2)](../man2/module_unload.md)
|
|
@ -1,25 +0,0 @@
|
|||
## Name
|
||||
|
||||
modload - load a kernel module
|
||||
|
||||
## Synopsis
|
||||
|
||||
```**sh
|
||||
$ modload <path>
|
||||
```
|
||||
|
||||
## Description
|
||||
|
||||
Load a kernel module specified by *path*.
|
||||
|
||||
## Examples
|
||||
|
||||
```sh
|
||||
$ modload /mod/TestModule.o
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
* [`modunload`(1)](modunload.md)
|
||||
* [`module_load`(2)](../man2/module_load.md)
|
||||
* [`kernel_modules`(7)](../man7/kernel_modules.md)
|
|
@ -1,25 +0,0 @@
|
|||
## Name
|
||||
|
||||
modunload - unload a kernel module
|
||||
|
||||
## Synopsis
|
||||
|
||||
```**sh
|
||||
$ modunload <name>
|
||||
```
|
||||
|
||||
## Description
|
||||
|
||||
Unload a kernel module specified by *name*.
|
||||
|
||||
## Examples
|
||||
|
||||
```sh
|
||||
$ modunload TestModule
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
* [`modload`(8)](modload.md)
|
||||
* [`module_unload`(2)](../man2/module_unload.md)
|
||||
* [`kernel_modules`(7)](../man7/kernel_modules.md)
|
|
@ -121,8 +121,6 @@ enum class NeedsBigProcessLock {
|
|||
S(mkdir, NeedsBigProcessLock::Yes) \
|
||||
S(mknod, NeedsBigProcessLock::Yes) \
|
||||
S(mmap, NeedsBigProcessLock::Yes) \
|
||||
S(module_load, NeedsBigProcessLock::Yes) \
|
||||
S(module_unload, NeedsBigProcessLock::Yes) \
|
||||
S(mount, NeedsBigProcessLock::Yes) \
|
||||
S(mprotect, NeedsBigProcessLock::Yes) \
|
||||
S(mremap, NeedsBigProcessLock::Yes) \
|
||||
|
|
|
@ -219,7 +219,6 @@ set(KERNEL_SOURCES
|
|||
Syscalls/mkdir.cpp
|
||||
Syscalls/mknod.cpp
|
||||
Syscalls/mmap.cpp
|
||||
Syscalls/module.cpp
|
||||
Syscalls/mount.cpp
|
||||
Syscalls/open.cpp
|
||||
Syscalls/perf_event.cpp
|
||||
|
@ -528,4 +527,3 @@ serenity_install_headers(Kernel)
|
|||
serenity_install_sources(Kernel)
|
||||
|
||||
add_subdirectory(Prekernel)
|
||||
add_subdirectory(Modules)
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include <Kernel/Interrupts/GenericInterruptHandler.h>
|
||||
#include <Kernel/Interrupts/InterruptManagement.h>
|
||||
#include <Kernel/KBufferBuilder.h>
|
||||
#include <Kernel/Module.h>
|
||||
#include <Kernel/Net/LocalSocket.h>
|
||||
#include <Kernel/Net/NetworkAdapter.h>
|
||||
#include <Kernel/Net/NetworkingManagement.h>
|
||||
|
@ -682,33 +681,7 @@ private:
|
|||
return KSuccess;
|
||||
}
|
||||
};
|
||||
class ProcFSModules final : public ProcFSGlobalInformation {
|
||||
public:
|
||||
static NonnullRefPtr<ProcFSModules> must_create();
|
||||
|
||||
virtual mode_t required_mode() const override { return 0400; }
|
||||
|
||||
private:
|
||||
ProcFSModules();
|
||||
virtual KResult try_generate(KBufferBuilder& builder) override
|
||||
{
|
||||
extern HashMap<String, OwnPtr<Module>>* g_modules;
|
||||
JsonArraySerializer array { builder };
|
||||
for (auto& it : *g_modules) {
|
||||
auto obj = array.add_object();
|
||||
obj.add("name", it.value->name);
|
||||
obj.add("module_init", it.value->module_init);
|
||||
obj.add("module_fini", it.value->module_fini);
|
||||
u32 size = 0;
|
||||
for (auto& section : it.value->sections) {
|
||||
size += section.capacity();
|
||||
}
|
||||
obj.add("size", size);
|
||||
}
|
||||
array.finish();
|
||||
return KSuccess;
|
||||
}
|
||||
};
|
||||
class ProcFSProfile final : public ProcFSGlobalInformation {
|
||||
public:
|
||||
static NonnullRefPtr<ProcFSProfile> must_create();
|
||||
|
@ -791,10 +764,6 @@ UNMAP_AFTER_INIT NonnullRefPtr<ProcFSCommandLine> ProcFSCommandLine::must_create
|
|||
{
|
||||
return adopt_ref_if_nonnull(new (nothrow) ProcFSCommandLine).release_nonnull();
|
||||
}
|
||||
UNMAP_AFTER_INIT NonnullRefPtr<ProcFSModules> ProcFSModules::must_create()
|
||||
{
|
||||
return adopt_ref_if_nonnull(new (nothrow) ProcFSModules).release_nonnull();
|
||||
}
|
||||
UNMAP_AFTER_INIT NonnullRefPtr<ProcFSProfile> ProcFSProfile::must_create()
|
||||
{
|
||||
return adopt_ref_if_nonnull(new (nothrow) ProcFSProfile).release_nonnull();
|
||||
|
@ -853,10 +822,6 @@ UNMAP_AFTER_INIT ProcFSCommandLine::ProcFSCommandLine()
|
|||
: ProcFSGlobalInformation("cmdline"sv)
|
||||
{
|
||||
}
|
||||
UNMAP_AFTER_INIT ProcFSModules::ProcFSModules()
|
||||
: ProcFSGlobalInformation("modules"sv)
|
||||
{
|
||||
}
|
||||
UNMAP_AFTER_INIT ProcFSProfile::ProcFSProfile()
|
||||
: ProcFSGlobalInformation("profile"sv)
|
||||
{
|
||||
|
@ -896,7 +861,6 @@ UNMAP_AFTER_INIT NonnullRefPtr<ProcFSRootDirectory> ProcFSRootDirectory::must_cr
|
|||
directory->m_components.append(ProcFSDevices::must_create());
|
||||
directory->m_components.append(ProcFSUptime::must_create());
|
||||
directory->m_components.append(ProcFSCommandLine::must_create());
|
||||
directory->m_components.append(ProcFSModules::must_create());
|
||||
directory->m_components.append(ProcFSProfile::must_create());
|
||||
directory->m_components.append(ProcFSKernelBase::must_create());
|
||||
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <Kernel/KBuffer.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
typedef void* (*ModuleInitPtr)();
|
||||
typedef void* (*ModuleFiniPtr)();
|
||||
|
||||
struct Module {
|
||||
String name;
|
||||
NonnullOwnPtrVector<KBuffer> sections;
|
||||
|
||||
ModuleInitPtr module_init { nullptr };
|
||||
ModuleFiniPtr module_fini { nullptr };
|
||||
};
|
||||
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
set(CMAKE_CXX_OUTPUT_EXTENSION_REPLACE 1)
|
||||
|
||||
function(serenity_kernel_module name sources)
|
||||
add_library(${name} STATIC ${sources})
|
||||
install(FILES $<TARGET_OBJECTS:${name}> DESTINATION mod)
|
||||
endfunction()
|
||||
|
||||
serenity_kernel_module(TestModule TestModule.cpp)
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Format.h>
|
||||
#include <Kernel/Modules/module_syms.h>
|
||||
|
||||
extern "C" const char module_name[] = "TestModule";
|
||||
|
||||
extern "C" void module_init()
|
||||
{
|
||||
dmesgln("TestModule has booted!");
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
dmesgln("i is now {}", i);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void module_fini()
|
||||
{
|
||||
dmesgln("TestModule is being removed!");
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2020, the SerenityOS developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" const char module_name[];
|
||||
extern "C" void module_init();
|
||||
extern "C" void module_fini();
|
|
@ -25,7 +25,6 @@
|
|||
#include <Kernel/Memory/AnonymousVMObject.h>
|
||||
#include <Kernel/Memory/PageDirectory.h>
|
||||
#include <Kernel/Memory/SharedInodeVMObject.h>
|
||||
#include <Kernel/Module.h>
|
||||
#include <Kernel/PerformanceEventBuffer.h>
|
||||
#include <Kernel/PerformanceManager.h>
|
||||
#include <Kernel/Process.h>
|
||||
|
@ -45,7 +44,6 @@ static void create_signal_trampoline();
|
|||
RecursiveSpinlock g_profiling_lock;
|
||||
static Atomic<pid_t> next_pid;
|
||||
static Singleton<SpinlockProtected<Process::List>> s_processes;
|
||||
READONLY_AFTER_INIT HashMap<String, OwnPtr<Module>>* g_modules;
|
||||
READONLY_AFTER_INIT Memory::Region* g_signal_trampoline_region;
|
||||
|
||||
static Singleton<MutexProtected<String>> s_hostname;
|
||||
|
@ -72,8 +70,6 @@ ProcessID Process::allocate_pid()
|
|||
|
||||
UNMAP_AFTER_INIT void Process::initialize()
|
||||
{
|
||||
g_modules = new HashMap<String, OwnPtr<Module>>;
|
||||
|
||||
next_pid.store(0, AK::MemoryOrder::memory_order_release);
|
||||
|
||||
// Note: This is called before scheduling is initialized, and before APs are booted.
|
||||
|
|
|
@ -393,8 +393,6 @@ public:
|
|||
KResultOr<FlatPtr> sys$getrandom(Userspace<void*>, size_t, unsigned int);
|
||||
KResultOr<FlatPtr> sys$getkeymap(Userspace<const Syscall::SC_getkeymap_params*>);
|
||||
KResultOr<FlatPtr> sys$setkeymap(Userspace<const Syscall::SC_setkeymap_params*>);
|
||||
KResultOr<FlatPtr> sys$module_load(Userspace<const char*> path, size_t path_length);
|
||||
KResultOr<FlatPtr> sys$module_unload(Userspace<const char*> name, size_t name_length);
|
||||
KResultOr<FlatPtr> sys$profiling_enable(pid_t, u64);
|
||||
KResultOr<FlatPtr> sys$profiling_disable(pid_t);
|
||||
KResultOr<FlatPtr> sys$profiling_free_buffer(pid_t);
|
||||
|
|
|
@ -1,168 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <Kernel/FileSystem/OpenFileDescription.h>
|
||||
#include <Kernel/FileSystem/VirtualFileSystem.h>
|
||||
#include <Kernel/KSyms.h>
|
||||
#include <Kernel/Module.h>
|
||||
#include <Kernel/Process.h>
|
||||
#include <LibELF/Image.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
extern HashMap<String, OwnPtr<Module>>* g_modules;
|
||||
|
||||
KResultOr<FlatPtr> Process::sys$module_load(Userspace<const char*> user_path, size_t path_length)
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
if (!is_superuser())
|
||||
return EPERM;
|
||||
|
||||
REQUIRE_NO_PROMISES;
|
||||
|
||||
auto path = TRY(get_syscall_path_argument(user_path, path_length));
|
||||
auto description = TRY(VirtualFileSystem::the().open(path->view(), O_RDONLY, 0, current_directory()));
|
||||
auto payload = TRY(description->read_entire_file());
|
||||
|
||||
auto storage = TRY(KBuffer::try_create_with_bytes(payload->bytes()));
|
||||
|
||||
auto elf_image = try_make<ELF::Image>(storage->data(), storage->size());
|
||||
if (!elf_image)
|
||||
return ENOMEM;
|
||||
if (!elf_image->parse())
|
||||
return ENOEXEC;
|
||||
|
||||
HashMap<String, u8*> section_storage_by_name;
|
||||
|
||||
auto module = try_make<Module>();
|
||||
if (!module)
|
||||
return ENOMEM;
|
||||
|
||||
KResult section_loading_result = KSuccess;
|
||||
elf_image->for_each_section_of_type(SHT_PROGBITS, [&](const ELF::Image::Section& section) {
|
||||
if (!section.size() || !section_loading_result.is_error())
|
||||
return;
|
||||
auto section_storage_or_error = KBuffer::try_create_with_bytes(ReadonlyBytes { section.raw_data(), section.size() }, Memory::Region::Access::ReadWriteExecute);
|
||||
if (section_storage_or_error.is_error()) {
|
||||
section_loading_result = section_storage_or_error.error();
|
||||
return;
|
||||
}
|
||||
auto section_storage = section_storage_or_error.release_value();
|
||||
section_storage_by_name.set(section.name(), section_storage->data());
|
||||
module->sections.append(move(section_storage));
|
||||
});
|
||||
if (section_loading_result.is_error())
|
||||
return section_loading_result;
|
||||
|
||||
bool missing_symbols = false;
|
||||
|
||||
elf_image->for_each_section_of_type(SHT_PROGBITS, [&](const ELF::Image::Section& section) {
|
||||
if (!section.size())
|
||||
return;
|
||||
|
||||
auto* section_storage = section_storage_by_name.get(section.name()).value_or(nullptr);
|
||||
VERIFY(section_storage);
|
||||
auto relocations = section.relocations();
|
||||
VERIFY(relocations.has_value());
|
||||
relocations->for_each_relocation([&](const ELF::Image::Relocation& relocation) {
|
||||
auto& patch_ptr = *reinterpret_cast<ptrdiff_t*>(section_storage + relocation.offset());
|
||||
switch (relocation.type()) {
|
||||
case R_386_PC32: {
|
||||
// PC-relative relocation
|
||||
dbgln("PC-relative relocation: {}", relocation.symbol().name());
|
||||
auto symbol_address = address_for_kernel_symbol(relocation.symbol().name());
|
||||
if (symbol_address == 0)
|
||||
missing_symbols = true;
|
||||
dbgln(" Symbol address: {:p}", symbol_address);
|
||||
ptrdiff_t relative_offset = (FlatPtr)symbol_address - ((FlatPtr)&patch_ptr + 4);
|
||||
patch_ptr = relative_offset;
|
||||
break;
|
||||
}
|
||||
case R_386_32: // Absolute relocation
|
||||
dbgln("Absolute relocation: '{}' value={}, index={}", relocation.symbol().name(), relocation.symbol().value(), relocation.symbol_index());
|
||||
|
||||
if (relocation.symbol().bind() == STB_LOCAL) {
|
||||
auto* section_storage_containing_symbol = section_storage_by_name.get(relocation.symbol().section().name()).value_or(nullptr);
|
||||
VERIFY(section_storage_containing_symbol);
|
||||
u32 symbol_address = (ptrdiff_t)(section_storage_containing_symbol + relocation.symbol().value());
|
||||
if (symbol_address == 0)
|
||||
missing_symbols = true;
|
||||
dbgln(" Symbol address: {:p}", symbol_address);
|
||||
patch_ptr += symbol_address;
|
||||
} else if (relocation.symbol().bind() == STB_GLOBAL) {
|
||||
u32 symbol_address = address_for_kernel_symbol(relocation.symbol().name());
|
||||
if (symbol_address == 0)
|
||||
missing_symbols = true;
|
||||
dbgln(" Symbol address: {:p}", symbol_address);
|
||||
patch_ptr += symbol_address;
|
||||
} else {
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (missing_symbols)
|
||||
return EINVAL;
|
||||
|
||||
auto* text_base = section_storage_by_name.get(".text").value_or(nullptr);
|
||||
if (!text_base) {
|
||||
dbgln("No .text section found in module!");
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
elf_image->for_each_symbol([&](const ELF::Image::Symbol& symbol) {
|
||||
dbgln(" - {} '{}' @ {:p}, size={}", symbol.type(), symbol.name(), symbol.value(), symbol.size());
|
||||
if (symbol.name() == "module_init") {
|
||||
module->module_init = (ModuleInitPtr)(text_base + symbol.value());
|
||||
} else if (symbol.name() == "module_fini") {
|
||||
module->module_fini = (ModuleFiniPtr)(text_base + symbol.value());
|
||||
} else if (symbol.name() == "module_name") {
|
||||
const u8* storage = section_storage_by_name.get(symbol.section().name()).value_or(nullptr);
|
||||
if (storage)
|
||||
module->name = String((const char*)(storage + symbol.value()));
|
||||
}
|
||||
});
|
||||
|
||||
if (!module->module_init)
|
||||
return EINVAL;
|
||||
|
||||
if (g_modules->contains(module->name)) {
|
||||
dbgln("a module with the name {} is already loaded; please unload it first", module->name);
|
||||
return EEXIST;
|
||||
}
|
||||
|
||||
module->module_init();
|
||||
|
||||
auto name = module->name;
|
||||
g_modules->set(name, move(module));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
KResultOr<FlatPtr> Process::sys$module_unload(Userspace<const char*> user_name, size_t name_length)
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
if (!is_superuser())
|
||||
return EPERM;
|
||||
|
||||
REQUIRE_NO_PROMISES;
|
||||
|
||||
auto module_name = TRY(try_copy_kstring_from_user(user_name, name_length));
|
||||
|
||||
auto it = g_modules->find(module_name->view());
|
||||
if (it == g_modules->end())
|
||||
return ENOENT;
|
||||
|
||||
if (it->value->module_fini)
|
||||
it->value->module_fini();
|
||||
|
||||
g_modules->remove(it);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -18,18 +18,6 @@ int disown(pid_t pid)
|
|||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int module_load(const char* path, size_t path_length)
|
||||
{
|
||||
int rc = syscall(SC_module_load, path, path_length);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int module_unload(const char* name, size_t name_length)
|
||||
{
|
||||
int rc = syscall(SC_module_unload, name, name_length);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int profiling_enable(pid_t pid, uint64_t event_mask)
|
||||
{
|
||||
int rc = syscall(SC_profiling_enable, pid, event_mask);
|
||||
|
|
|
@ -16,9 +16,6 @@ __BEGIN_DECLS
|
|||
|
||||
int disown(pid_t);
|
||||
|
||||
int module_load(const char* path, size_t path_length);
|
||||
int module_unload(const char* name, size_t name_length);
|
||||
|
||||
int profiling_enable(pid_t, uint64_t);
|
||||
int profiling_disable(pid_t);
|
||||
int profiling_free_buffer(pid_t);
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibCore/ArgsParser.h>
|
||||
#include <serenity.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
const char* path = nullptr;
|
||||
|
||||
Core::ArgsParser args_parser;
|
||||
args_parser.add_positional_argument(path, "Path to the module to load", "path");
|
||||
args_parser.parse(argc, argv);
|
||||
|
||||
int rc = module_load(path, strlen(path));
|
||||
if (rc < 0) {
|
||||
perror("module_load");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibCore/ArgsParser.h>
|
||||
#include <serenity.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
const char* name = nullptr;
|
||||
|
||||
Core::ArgsParser args_parser;
|
||||
args_parser.add_positional_argument(name, "Name of the module to unload", "name");
|
||||
args_parser.parse(argc, argv);
|
||||
|
||||
int rc = module_unload(name, strlen(name));
|
||||
if (rc < 0) {
|
||||
perror("module_unload");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue