The Pedigree Project 0.1
init-module-syscalls.cc
1/* Copyright (c) 2026, Pedigree Developers. */
2#include "init-module-syscalls.h"
3#include "pedigree/kernel/linker/KernelElf.h"
4#include "pedigree/kernel/process/Process.h"
5#include "pedigree/kernel/process/TerminationDeferral.h"
6#include "pedigree/kernel/process/Thread.h"
7#include "pedigree/kernel/processor/Processor.h"
8#include "pedigree/kernel/processor/ProcessorInformation.h"
9#include "pedigree/kernel/syscallError.h"
10
11#include "PosixSubsystem.h"
12#include "user-namespace.h"
13
14int posix_init_module(const void* image, size_t length, const char* parameters) {
15 TerminationDeferral lifetime;
16 Thread* thread = Processor::information().getCurrentThread();
17 if (!posix_global_capable(16)) {
18 SYSCALL_ERROR(NotEnoughPermissions);
19 return -1;
20 }
21 // Native Pedigree modules have no Linux module-parameter parser.
22 char first = 0;
23 if (!PosixSubsystem::copyFromUser(&first, parameters, sizeof(first))) {
24 SYSCALL_ERROR(BadAddress);
25 return -1;
26 }
27 if (first) {
28 SYSCALL_ERROR(OperationNotSupported);
29 return -1;
30 }
31 auto& kernel = KernelElf::instance();
32 using Result = KernelElf::RuntimeLoadResult;
33 Result result = Result::Busy;
34 bool copyFailed = false;
35 {
37 result = kernel.beginRuntimeModuleLoad(length, load);
38 if (result == Result::Ready) {
39 copyFailed = !PosixSubsystem::copyFromUser(load.data(), image, length);
40 if (!copyFailed)
41 result = kernel.loadModuleRuntime(load);
42 }
43 }
44 // Failed entry cleanup may itself call interfaces which set errno.
45 if (copyFailed) {
46 SYSCALL_ERROR(BadAddress);
47 return -1;
48 }
49 switch (result) {
50 case Result::Loaded:
51 thread->setErrno(0);
52 return 0;
53 case Result::InvalidImage:
54 case Result::UnsupportedImage:
55 case Result::ImageTooLarge:
56 SYSCALL_ERROR(ExecFormatError);
57 break;
58 case Result::NoMemory:
59 SYSCALL_ERROR(OutOfMemory);
60 break;
61 case Result::Shutdown:
62 SYSCALL_ERROR(NotEnoughPermissions);
63 break;
64 case Result::Duplicate:
65 SYSCALL_ERROR(FileExists);
66 break;
67 case Result::MissingDependency:
68 SYSCALL_ERROR(DoesNotExist);
69 break;
70 case Result::EntryFailed:
71 SYSCALL_ERROR(DeviceDoesNotExist);
72 break;
73 case Result::ProtectionFailed:
74 SYSCALL_ERROR(IoError);
75 break;
76 case Result::Ready:
77 case Result::Busy:
78 SYSCALL_ERROR(DeviceBusy);
79 break;
80 }
81 return -1;
82}
static KernelElf & instance()
Definition KernelElf.h:135
static bool copyFromUser(void *destination, const void *source, size_t count, size_t elementSize=1)
static ProcessorInformation & information()
void setErrno(size_t err)
Definition Thread.h:482