20#include "pedigree/kernel/Log.h"
21#include "pedigree/kernel/process/Scheduler.h"
22#include "pedigree/kernel/process/Uninterruptible.h"
23#include "pedigree/kernel/processor/PhysicalMemoryManager.h"
24#include "pedigree/kernel/processor/SyscallManager.h"
25#include "pedigree/kernel/syscallError.h"
27#include "file-syscalls.h"
28#include "linux-amd64-signal-abi.h"
29#include "linux-amd64-signal.h"
30#include "linux-wait-abi.h"
31#include "pthread-syscalls.h"
32#include "signal-syscalls.h"
33#include "system-syscalls.h"
35#define MACHINE_FORWARD_DECL_ONLY
36#include "pedigree/kernel/Subsystem.h"
37#include "pedigree/kernel/machine/Machine.h"
38#include "pedigree/kernel/machine/Timer.h"
40#include <PosixProcess.h>
41#include <PosixSubsystem.h>
46extern void sigret_stub();
47extern char sigret_stub_end;
51static constexpr int SignalQueueFull = -2;
52static int doProcessKill(
Process* p,
int sig);
53static int doThreadKill(
Thread* p,
int sig);
54static int queueThreadSignal(
Process* process,
Thread* thread,
int sig);
58#define SIGNAL_HANDLER_EXIT(name, errcode) \
59 static void name(int) { \
60 Processor::information().getCurrentThread()->deferSignalExit(errcode); \
62#define SIGNAL_HANDLER_EMPTY(name) \
63 static void name(int s) { \
64 NOTICE("EMPTY handler."); \
66#define SIGNAL_HANDLER_EXITMSG(name, errcode, msg) \
67 static void name(int) { \
68 Processor::setInterrupts(true); \
69 posix_write(1, msg, StringLength(msg), true); \
70 Scheduler::instance().yield(); \
71 Processor::information().getCurrentThread()->deferSignalExit(errcode); \
73static char SSIGILL[] =
"Illegal instruction.\n";
74static char SSIGSEGV[] =
"Segmentation fault.\n";
75static char SSIGBUS[] =
"Bus error.\n";
76static char SSIGABRT[] =
"Abort.\n";
78SIGNAL_HANDLER_EXITMSG(sigabrt, SIGABRT, SSIGABRT)
79SIGNAL_HANDLER_EXIT(sigalrm, SIGALRM)
80SIGNAL_HANDLER_EXITMSG(sigbus, SIGBUS, SSIGBUS)
81SIGNAL_HANDLER_EMPTY(sigchld)
82static void sigcont(
int) {}
83SIGNAL_HANDLER_EXIT(sigfpe, SIGFPE)
84SIGNAL_HANDLER_EXIT(sighup, SIGHUP)
85SIGNAL_HANDLER_EXITMSG(sigill, SIGILL, SSIGILL)
86SIGNAL_HANDLER_EXIT(sigint, SIGINT)
87SIGNAL_HANDLER_EXIT(sigkill, SIGKILL)
88SIGNAL_HANDLER_EXIT(sigpipe, SIGPIPE)
89SIGNAL_HANDLER_EXIT(sigquit, SIGQUIT)
90SIGNAL_HANDLER_EXITMSG(sigsegv, SIGSEGV, SSIGSEGV)
91SIGNAL_HANDLER_EXIT(sigstkflt, SIGSTKFLT)
92SIGNAL_HANDLER_EXIT(sigterm, SIGTERM)
93SIGNAL_HANDLER_EXIT(sigtrap, SIGTRAP)
94SIGNAL_HANDLER_EXIT(sigusr1, SIGUSR1)
95SIGNAL_HANDLER_EXIT(sigusr2, SIGUSR2)
96SIGNAL_HANDLER_EMPTY(sigurg)
97SIGNAL_HANDLER_EXIT(sigxcpu, SIGXCPU)
98SIGNAL_HANDLER_EXIT(sigxfsz, SIGXFSZ)
99SIGNAL_HANDLER_EXIT(sigvtalrm, SIGVTALRM)
100SIGNAL_HANDLER_EXIT(sigprof, SIGPROF)
101SIGNAL_HANDLER_EXIT(sigio, SIGIO)
102SIGNAL_HANDLER_EXIT(sigpwr, SIGPWR)
103SIGNAL_HANDLER_EXIT(sigsys, SIGSYS)
104SIGNAL_HANDLER_EXIT(sigtimer, 32)
105SIGNAL_HANDLER_EXIT(sigcancel, 33)
106SIGNAL_HANDLER_EXIT(sigsynccall, 34)
108SIGNAL_HANDLER_EMPTY(sigign);
110static
void suspendForDefaultSignal(
int) {
113 size_t continuationEpoch = 0;
115 ERROR(
"Default stop handler did not receive trusted signal metadata.");
118 if (signal != SIGSTOP && signal != SIGTSTP && signal != SIGTTIN && signal != SIGTTOU) {
119 ERROR(
"Default stop handler received non-stop signal " <<
Dec << signal <<
".");
124 NOTICE(
"SUSPEND [pid=" << process->
getId() <<
", signal " << signal <<
"]");
128static _sig_func_ptr default_sig_handlers[PosixSubsystem::SignalDispositionCount] = {
148 suspendForDefaultSignal,
149 suspendForDefaultSignal,
150 suspendForDefaultSignal,
151 suspendForDefaultSignal,
166static void realtimeDefault(
int) {
168 size_t signal = 0, epoch = 0;
173uintptr_t pedigree_default_signal_handler(
size_t signal) {
174 if (signal >= 35 && signal <= PosixSubsystem::MaximumSupportedSignal)
175 return reinterpret_cast<uintptr_t
>(realtimeDefault);
176 return signal < PosixSubsystem::SignalDispositionCount
177 ?
reinterpret_cast<uintptr_t
>(default_sig_handlers[signal])
181static int posix_sigaction_impl(
int sig,
const struct sigaction* act,
struct sigaction* oact,
182 bool allowLinuxPrivateSignals) {
187 ERROR(
"posix_sigaction: no subsystem");
192 if ((sig <= 0) || (sig >
static_cast<int>(PosixSubsystem::MaximumSupportedSignal)) ||
193 (!allowLinuxPrivateSignals &&
195 (sig == SIGKILL || sig == SIGSTOP)) {
196 SYSCALL_ERROR(InvalidArgument);
200 uintptr_t newHandler = 0;
203 newHandler =
reinterpret_cast<uintptr_t
>(act->sa_handler);
204 if (newHandler == 0) {
205 SG_NOTICE(
" + SIG_DFL");
206 newHandler = pedigree_default_signal_handler(sig);
208 }
else if (newHandler == 1) {
209 SG_NOTICE(
" + SIG_IGN");
210 newHandler =
reinterpret_cast<uintptr_t
>(sigign);
212 }
else if (newHandler ==
static_cast<uintptr_t
>(-1)) {
213 SG_NOTICE(
" + Invalid");
214 SYSCALL_ERROR(InvalidArgument);
219 SG_NOTICE(
" + Handler is not executable userspace memory");
220 SYSCALL_ERROR(BadAddress);
230 ByteSet(oact, 0,
sizeof(
struct sigaction));
232 oact->sa_flags = oldDisposition.flags;
233 oact->sa_restorer =
reinterpret_cast<void (*)()
>(oldDisposition.restorer);
234 MemoryCopy(&oact->sa_mask, &oldDisposition.signalMask,
sizeof(oldDisposition.signalMask));
235 if (oldDisposition.type == 0)
236 oact->sa_handler =
reinterpret_cast<void (*)(
int)
>(oldDisposition.handler);
237 else if (oldDisposition.type == 1)
238 oact->sa_handler =
reinterpret_cast<void (*)(
int)
>(0);
239 else if (oldDisposition.type == 2)
240 oact->sa_handler =
reinterpret_cast<void (*)(
int)
>(1);
246 bool legacyUserHandler = handlerType == 0;
248 legacyUserHandler = legacyUserHandler && pSubsystem->
getAbi() != PosixSubsystem::LinuxAbi;
251 sigHandler->
flags = act->sa_flags;
252 sigHandler->
restorer =
reinterpret_cast<uintptr_t
>(act->sa_restorer);
253 sigHandler->
type = handlerType;
254 MemoryCopy(&sigHandler->
sigMask, &act->sa_mask,
sizeof(sigHandler->
sigMask));
257 if (handlerType == 0 && !legacyUserHandler) {
259 newHandler,
static_cast<size_t>(sig), sigHandler->
sigMask,
261 sigHandler->
flags & SA_ONSTACK);
266 newHandler,
static_cast<size_t>(sig), ~0UL, sigHandler->
sigMask,
267 !(sigHandler->
flags & SA_NODEFER),
false,
268 handlerType == 0 ? Event::HandlerPrivilege::User :
Event::HandlerPrivilege::Kernel,
269 handlerType == 0 ?
SignalEvent::DeliveryDisposition::CaughtHandler
271 handlerType == 0 && (sigHandler->flags & SA_ONSTACK));
273 if (legacyUserHandler && !pSubsystem->admitLegacyUserSignals()) {
275 SYSCALL_ERROR(OperationNotSupported);
278 SG_NOTICE(
"Creating the event (" <<
reinterpret_cast<uintptr_t
>(sigHandler->
pEvent) <<
").");
282 SYSCALL_ERROR(InvalidArgument);
288int posix_sigaction(
int sig,
const struct sigaction* act,
struct sigaction* oact) {
289 SG_NOTICE(
"sigaction(" <<
Dec << sig <<
Hex <<
", " <<
reinterpret_cast<uintptr_t
>(act) <<
", "
290 <<
reinterpret_cast<uintptr_t
>(oact) <<
")");
291 struct sigaction requested = {};
294 PosixSubsystem::SafeWrite))) {
295 SYSCALL_ERROR(BadAddress);
299 struct sigaction previous = {};
301 posix_sigaction_impl(sig, act ? &requested : nullptr, oact ? &previous : nullptr, false);
303 SYSCALL_ERROR(BadAddress);
310struct LinuxArmv7KernelSigaction {
317static_assert(
sizeof(LinuxArmv7KernelSigaction) == 20);
319int posix_linux_armv7_sigaction(
int sig,
const LinuxArmv7KernelSigaction* act,
320 LinuxArmv7KernelSigaction* oact) {
321 LinuxArmv7KernelSigaction linuxAct = {};
324 PosixSubsystem::SafeWrite))) {
325 SYSCALL_ERROR(BadAddress);
329 struct sigaction nativeAct = {};
331 nativeAct.sa_handler =
reinterpret_cast<void (*)(
int)
>(linuxAct.handler);
332 nativeAct.sa_flags = linuxAct.flags;
333 nativeAct.sa_restorer =
reinterpret_cast<void (*)()
>(linuxAct.restorer);
334 MemoryCopy(&nativeAct.sa_mask, &linuxAct.mask,
sizeof(linuxAct.mask));
337 struct sigaction nativeOld = {};
339 posix_sigaction_impl(sig, act ? &nativeAct : nullptr, oact ? &nativeOld : nullptr, true);
340 if (result == 0 && oact) {
341 LinuxArmv7KernelSigaction linuxOld = {};
342 linuxOld.handler =
reinterpret_cast<uintptr_t
>(nativeOld.sa_handler);
343 linuxOld.flags = nativeOld.sa_flags;
344 linuxOld.restorer =
reinterpret_cast<uintptr_t
>(nativeOld.sa_restorer);
345 MemoryCopy(&linuxOld.mask, &nativeOld.sa_mask,
sizeof(linuxOld.mask));
347 SYSCALL_ERROR(BadAddress);
364 "Linux amd64 kernel sigaction layout must remain 32 bytes");
365static_assert(
sizeof(stack_t) == 24 && __builtin_offsetof(stack_t, ss_flags) == 8 &&
366 __builtin_offsetof(stack_t, ss_size) == 16,
367 "Linux amd64 sigaltstack layout must remain 24 bytes");
371 SG_NOTICE(
"linux-amd64 sigaction(" <<
Dec << sig <<
Hex <<
", "
372 <<
reinterpret_cast<uintptr_t
>(act) <<
", "
373 <<
reinterpret_cast<uintptr_t
>(oact) <<
")");
378 PosixSubsystem::SafeWrite))) {
379 SYSCALL_ERROR(BadAddress);
383 struct sigaction nativeAct = {};
384 const struct sigaction* nativeActPtr =
nullptr;
386 nativeAct.sa_handler =
387 reinterpret_cast<void (*)(
int)
>(
static_cast<uintptr_t
>(linuxAct.handler));
388 nativeAct.sa_flags =
static_cast<int>(linuxAct.flags);
389 nativeAct.sa_restorer =
reinterpret_cast<void (*)()
>(
static_cast<uintptr_t
>(linuxAct.restorer));
390 MemoryCopy(&nativeAct.sa_mask, &linuxAct.mask,
sizeof(linuxAct.mask));
391 nativeActPtr = &nativeAct;
394 struct sigaction nativeOld = {};
395 struct sigaction* nativeOldPtr = oact ? &nativeOld :
nullptr;
396 int result = posix_sigaction_impl(sig, nativeActPtr, nativeOldPtr,
true);
397 if ((result == 0) && oact) {
399 linuxOld.handler =
reinterpret_cast<uintptr_t
>(nativeOld.sa_handler);
400 linuxOld.flags =
static_cast<uint64_t
>(
static_cast<uint32_t
>(nativeOld.sa_flags));
401 linuxOld.restorer =
reinterpret_cast<uintptr_t
>(nativeOld.sa_restorer);
402 MemoryCopy(&linuxOld.mask, &nativeOld.sa_mask,
sizeof(linuxOld.mask));
404 SYSCALL_ERROR(BadAddress);
413uintptr_t posix_signal(
int sig,
void* func) {
414 ERROR(
"signal called but glue signal should redirect to sigaction");
418int posix_raise(
int sig) {
426 ERROR(
"posix_raise: no subsystem");
435 PosixSubsystem::SignalDeliveryResult::Full) {
436 SYSCALL_ERROR(NoMoreProcesses);
445int pedigree_sigret() {
446 SG_NOTICE(
"pedigree_sigret");
449 SYSCALL_ERROR(InvalidArgument);
455int pedigree_unwind_signal() {
456 SG_NOTICE(
"pedigree_unwind_signal");
459 SYSCALL_ERROR(InvalidArgument);
465static int doThreadKill(
Thread* p,
int sig) {
469 ERROR(
"posix_kill: no subsystem on process " << p->
getParent()->
getId());
473 PosixSubsystem::SignalDeliveryResult::Full) {
474 SYSCALL_ERROR(NoMoreProcesses);
475 return SignalQueueFull;
481static int doProcessKill(
Process* p,
int sig) {
487 const int64_t callerReal = caller->
getUserId();
488 const int64_t callerEffective = caller->getEffectiveUserId();
489 if (callerEffective == 0) {
493 const int64_t targetReal = target->
getUserId();
494 const int64_t targetSaved = target->getSavedUserId();
495 const bool realMatches = callerReal >= 0 && (callerReal == targetReal ||
496 (targetSaved >= 0 && callerReal == targetSaved));
497 const bool effectiveMatches =
498 callerEffective >= 0 &&
499 (callerEffective == targetReal || (targetSaved >= 0 && callerEffective == targetSaved));
500 if (realMatches || effectiveMatches) {
504 return sig == SIGCONT && caller->sharesSession(*target);
507static int queueThreadSignal(
Process* process,
Thread* thread,
int sig) {
514 SYSCALL_ERROR(InvalidArgument);
518 const PosixSubsystem::SignalDeliveryResult result =
520 if (result == PosixSubsystem::SignalDeliveryResult::Full) {
521 SYSCALL_ERROR(NoMoreProcesses);
524 if (result == PosixSubsystem::SignalDeliveryResult::Unavailable) {
525 SYSCALL_ERROR(InvalidArgument);
534int posix_tkill(
int tid,
int sig,
bool linuxAbi) {
535 SG_NOTICE(
"tkill(" << tid <<
", " << sig <<
")");
538 SYSCALL_ERROR(InvalidArgument);
547 : caller->acquireThreadById(thread, tid)) ||
548 thread->getParent()->getType() !=
Process::Posix) {
549 SYSCALL_ERROR(NoSuchProcess);
553 if (sig < 0 || sig >
static_cast<int>(PosixSubsystem::MaximumSupportedSignal)) {
554 SYSCALL_ERROR(InvalidArgument);
559 if (caller->getType() != Process::Posix ||
560 (caller != target && !canSignalProcess(
static_cast<PosixProcess*
>(caller),
562 SYSCALL_ERROR(NotEnoughPermissions);
565 return queueThreadSignal(target, thread.get(), sig);
568int posix_tgkill(
int tgid,
int tid,
int sig,
bool linuxAbi) {
569 SG_NOTICE(
"tgkill(" << tgid <<
", " << tid <<
", " << sig <<
")");
571 if (tgid <= 0 || tid <= 0) {
572 SYSCALL_ERROR(InvalidArgument);
578 if (!
Scheduler::instance().acquireProcessByUserspaceId(process,
static_cast<size_t>(tgid)) ||
579 process->getType() != Process::Posix ||
581 ? process->acquireThreadByUserspaceId(
582 thread,
static_cast<size_t>(tid),
584 : process->acquireThreadById(thread, static_cast<size_t>(tid)))) {
585 SYSCALL_ERROR(NoSuchProcess);
589 if (sig < 0 || sig >
static_cast<int>(PosixSubsystem::MaximumSupportedSignal)) {
590 SYSCALL_ERROR(InvalidArgument);
596 if (!callerProcess || callerProcess->getType() != Process::Posix) {
597 SYSCALL_ERROR(NotEnoughPermissions);
603 if (callerProcess != process.get() && !canSignalProcess(caller, target, sig)) {
604 SYSCALL_ERROR(NotEnoughPermissions);
608 const int result = queueThreadSignal(process.get(), thread.get(), sig);
614int posix_kill(
int pid,
int sig) {
615 SG_NOTICE(
"kill(" << pid <<
", " << sig <<
")");
619 if (sig < 0 || sig >
static_cast<int>(PosixSubsystem::MaximumSupportedSignal) ||
620 (sig >= 32 && sig <= 34)) {
621 SYSCALL_ERROR(InvalidArgument);
630 size_t thisGroupId = 0;
631 const bool thisHasGroup =
632 pThisProcess->getProcessGroupId(thisGroupId, pThisProcess->pidNamespace().
get());
634 bool bKillingSelf =
false;
635 bool foundTarget =
false;
644 Process* pProcess = process.get();
650 if (pProcess->getType() != Process::Posix) {
658 bool selected =
false;
661 static_cast<int>(pProcess->
getUserspaceId(pThisProcess->pidNamespace().
get())) == pid;
664 const bool hasGroup =
665 pPosixProcess->getProcessGroupId(groupId, pThisProcess->pidNamespace().
get());
668 selected = hasGroup && thisHasGroup && groupId == thisGroupId;
670 SC_NOTICE(
" -> selecting process " << pProcess->
getId() <<
" in group [" << groupId
673 }
else if (pid == -1) {
677 pProcess != pThisProcess;
680 selected = hasGroup && groupId ==
static_cast<size_t>(-
static_cast<int64_t
>(pid));
689 if (!canSignalProcess(pThisProcess, pPosixProcess, sig)) {
697 if (processList.
count() == 0) {
699 SYSCALL_ERROR(NotEnoughPermissions);
700 SG_NOTICE(
" -> target exists, but permission was denied");
702 SYSCALL_ERROR(NoSuchProcess);
703 SG_NOTICE(
" -> no such process");
714 bool accepted =
false;
715 bool quotaFailed =
false;
722 member->getType() != Process::Posix) {
725 SG_NOTICE(
" -> not killing current process, killing " << member->
getId());
726 NOTICE(
"sending #" <<
Dec << member->
getId() <<
" signal #" << sig <<
" from #"
727 << pThisProcess->
getId());
728 const int result = doProcessKill(member.get(), sig);
729 accepted |= result == 0;
730 quotaFailed |= result == SignalQueueFull;
732 SG_NOTICE(
" -> killing current process (" << pThisProcess->
getId() <<
")");
741 SG_NOTICE(
"performing kill of " << pThisProcess->
getId() <<
"...");
742 NOTICE(
"sending self #" <<
Dec << pThisProcess->
getId() <<
" signal #" << sig);
743 const int result = doProcessKill(pThisProcess, sig);
744 accepted |= result == 0;
745 quotaFailed |= result == SignalQueueFull;
748 if (!accepted && quotaFailed) {
749 SYSCALL_ERROR(NoMoreProcesses);
755int posix_sigprocmask(
int how,
const void* set,
void* oset,
size_t sigsetSize,
bool linuxCompat) {
756 constexpr size_t KernelSigsetSize =
sizeof(uint64_t);
757 constexpr uint64_t UnblockableSignals =
758 (
static_cast<uint64_t
>(1) << (SIGKILL - 1)) | (
static_cast<uint64_t
>(1) << (SIGSTOP - 1));
759 static_assert(
sizeof(sigset_t) >= KernelSigsetSize,
760 "native sigset_t must hold Pedigree's signal mask");
762 if (linuxCompat && sigsetSize != KernelSigsetSize) {
763 SYSCALL_ERROR(InvalidArgument);
767 const size_t userSigsetSize = linuxCompat ? KernelSigsetSize :
sizeof(sigset_t);
768 sigset_t requestedSet = {};
769 uint64_t requestedMask = 0;
772 SYSCALL_ERROR(BadAddress);
775 if (how != SIG_BLOCK && how != SIG_UNBLOCK && how != SIG_SETMASK) {
776 SYSCALL_ERROR(InvalidArgument);
779 MemoryCopy(&requestedMask, &requestedSet, KernelSigsetSize);
785 sigset_t previousSet = {};
786 MemoryCopy(&previousSet, &oldMask, KernelSigsetSize);
788 SYSCALL_ERROR(BadAddress);
794 uint64_t newMask = oldMask;
795 if (how == SIG_BLOCK) {
796 newMask |= requestedMask;
797 }
else if (how == SIG_UNBLOCK) {
798 newMask &= ~requestedMask;
800 newMask = requestedMask;
810int posix_rt_sigsuspend(
const uint64_t* signalMask,
size_t signalMaskSize) {
811 constexpr size_t KernelSigsetSize =
sizeof(uint64_t);
812 constexpr uint64_t UnblockableSignals =
813 (
static_cast<uint64_t
>(1) << (SIGKILL - 1)) | (
static_cast<uint64_t
>(1) << (SIGSTOP - 1));
815 if (signalMaskSize != KernelSigsetSize) {
816 SYSCALL_ERROR(InvalidArgument);
820 uint64_t temporaryMask = 0;
822 SYSCALL_ERROR(BadAddress);
825 temporaryMask &= ~UnblockableSignals;
829 FATAL(
"rt_sigsuspend has no current Thread.");
838 SYSCALL_ERROR(Interrupted);
842size_t posix_alarm(uint32_t seconds) {
843 SG_NOTICE(
"alarm(" << seconds <<
")");
847 if (!process || process->getType() != Process::Posix) {
848 ERROR(
"posix_alarm: no POSIX process");
853 Time::Timestamp previousValue = 0;
855 0,
static_cast<Time::Timestamp
>(seconds) * Time::Multiplier::Second,
nullptr, &previousValue);
857 Time::Timestamp previousSeconds = previousValue / Time::Multiplier::Second;
858 const Time::Timestamp subsecond = previousValue % Time::Multiplier::Second;
861 if ((!previousSeconds && subsecond) || subsecond >= (Time::Multiplier::Second / 2)) {
864 return static_cast<uint32_t
>(previousSeconds);
867int posix_sleep(uint32_t seconds) {
871 const bool completed = Time::delay(seconds * Time::Multiplier::Second);
873 if (!completed && thread->getInterruptionReason() == Thread::InterruptedBySignal) {
875 uint64_t elapsed = endTick - startTick;
876 uint32_t elapsedSecs =
static_cast<uint32_t
>(elapsed / 1000);
877 thread->clearInterruption();
879 if (elapsedSecs >= seconds)
882 return seconds - elapsedSecs;
888int posix_usleep(
size_t useconds) {
891 const bool completed = Time::delay(useconds * Time::Multiplier::Microsecond);
893 if (!completed && thread->getInterruptionReason() == Thread::InterruptedBySignal) {
894 thread->clearInterruption();
895 SYSCALL_ERROR(Interrupted);
902int posix_sigaltstack(
const stack_t* stack, stack_t* oldstack) {
903 stack_t requested = {};
905 SYSCALL_ERROR(BadAddress);
909 if (requested.ss_flags & ~SS_DISABLE) {
910 SYSCALL_ERROR(InvalidArgument);
918 if (stack && currStack.inUse) {
919 SYSCALL_ERROR(NotEnoughPermissions);
923 if (stack && !(requested.ss_flags & SS_DISABLE)) {
924 uintptr_t base =
reinterpret_cast<uintptr_t
>(requested.ss_sp);
925 if (requested.ss_size < MINSIGSTKSZ) {
926 SYSCALL_ERROR(OutOfMemory);
929 if (!base || requested.ss_size > (~
static_cast<uintptr_t
>(0) - base) ||
931 SYSCALL_ERROR(BadAddress);
937 stack_t previous = {};
938 if (currStack.enabled) {
939 previous.ss_sp =
reinterpret_cast<void*
>(currStack.base);
940 previous.ss_size = currStack.size;
941 previous.ss_flags = currStack.inUse ? SS_ONSTACK : 0;
943 previous.ss_flags = SS_DISABLE;
946 SYSCALL_ERROR(BadAddress);
952 if (requested.ss_flags & SS_DISABLE) {
955 currStack.enabled =
false;
957 currStack.base =
reinterpret_cast<uintptr_t
>(requested.ss_sp);
958 currStack.size = requested.ss_size;
959 currStack.enabled =
true;
966void pedigree_init_sigret() {
967 SG_NOTICE(
"init_sigret");
968 static physical_uintptr_t sigretPhys = 0;
971 if (sigretPhys == 0) {
983 (
reinterpret_cast<uintptr_t
>(&sigret_stub_end) -
reinterpret_cast<uintptr_t
>(sigret_stub)));
1006 pProcess->setSubsystem(pSubsystem);
1010 pedigree_reset_signals_for_exec(pThread);
1013void pedigree_reset_signals_for_exec(
Thread* pThread) {
1014 if (!pThread || !pThread->
getParent()) {
1015 FATAL(
"Cannot reset exec signal state without a process thread.");
1020 FATAL(
"Cannot reset exec signal state without a POSIX subsystem.");
1025 for (
size_t i = 0; i < PosixSubsystem::SignalDispositionCount; i++) {
1028 int signalDisposition = 1;
1032 if (existingDisposition.type == 2) {
1033 signalDisposition = 2;
1041 sigHandler->
sig = i;
1042 sigHandler->
type = signalDisposition;
1044 uintptr_t newHandler = signalDisposition == 1 ? pedigree_default_signal_handler(i)
1045 : reinterpret_cast<uintptr_t>(sigign);
1048 new SignalEvent(newHandler, i, ~0UL, 0,
true,
false, Event::HandlerPrivilege::Kernel,
1049 SignalEvent::DeliveryDisposition::DefaultAction);
1051 replacements[i] = sigHandler;
1057 SG_NOTICE(
"Creating initial set of signal handlers is complete");
static uintptr_t getTrampoline()
void setIntervalAndValue(Time::Timestamp interval, Time::Timestamp value, Time::Timestamp *prevInterval=nullptr, Time::Timestamp *prevValue=nullptr)
Set both interval and value atomically.
::Iterator< T, node_t > Iterator
virtual Timer * getTimer()=0
virtual physical_uintptr_t allocatePage(size_t pageConstraints=0)=0
static PhysicalMemoryManager & instance()
virtual void pin(physical_uintptr_t page)=0
int64_t getUserId() const final
void resetSignalHandlersForExec(Thread *thread, SignalHandler *const handlers[SignalDispositionCount])
static bool copyFromUser(void *destination, const void *source, size_t count, size_t elementSize=1)
static constexpr size_t LinuxPrivateSignalFirst
void setProcess(Process *process) override
SignalDeliveryResult queueSignalDelivery(Thread *target, size_t sig, uint32_t *flags=nullptr, int32_t signalCode=0, bool processDirected=false, uint64_t signalValue=0, const SharedPointer< SignalEventState > &state=SharedPointer< SignalEventState >())
static bool copyToUser(void *destination, const void *source, size_t count, size_t elementSize=1)
void setSignalHandler(size_t sig, SignalHandler *handler)
bool getSignalDisposition(size_t sig, SignalDisposition &disposition, bool beginDelivery=false)
static bool checkAddress(uintptr_t addr, size_t extent, size_t flags)
size_t getUserspaceId() const
MUST_USE_RESULT bool acquireProcessSignalThread(ThreadLease &lease)
void suspendIfContinuationEpoch(int stopSignal, size_t continuationEpoch)
static ProcessorInformation & information()
static Scheduler & instance()
MUST_USE_RESULT bool acquireProcess(ProcessLease &lease, size_t n)
static EXPORTED_PUBLIC SyscallManager & instance()
@ Continue
No unwind necessary, carry on as normal.
void deferSignalExit(int signal)
UnwindType getUnwindState()
Process * getParent() const
void prepareSignalStateForExec()
void setSignalMask(uint64_t mask)
bool waitForEventOrSignalInterruption(WaitQueue::StackDiscardCleanup onStackDiscard=nullptr, void *stackDiscardContext=nullptr)
bool getCurrentSignalDelivery(size_t &signalNumber, size_t &continuationEpoch)
virtual uint64_t getTickCount()=0
static const size_t RuntimeMapping
static const size_t Shared
static const size_t Write
static const size_t Execute
void pushBack(const T &value)
int type
Type - 0 = normal, 1 = SIG_DFL, 2 = SIG_IGN.
SignalEvent * pEvent
Event for the signal handler.
uintptr_t restorer
Userspace restorer for Linux-compatible signal delivery.
uint64_t sigMask
Signal mask to set when this signal handler is called.
uint32_t flags
Signal handler flags.