Add InitTrampoline and HasPendingSignal function

This commit is contained in:
EnderIce2 2024-03-03 23:58:05 +02:00
parent e69ace7fdc
commit c2b595452e
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
2 changed files with 68 additions and 52 deletions

View File

@ -21,7 +21,7 @@
#include <syscalls.hpp>
#include <lock.hpp>
#include <types.h>
#include <vector>
#include <list>
#include <syscall/linux/signals.hpp>
enum Signals : int
@ -388,11 +388,11 @@ namespace Tasking
void *TrampAddr = nullptr;
size_t TrampSz = 0;
std::vector<SignalInfo> SignalQueue;
std::list<SignalInfo> SignalQueue;
std::atomic<sigset_t> SignalMask = 0;
sigaction SignalAction[SIGNAL_MAX]{};
SignalDisposition sigDisp[SIGNAL_MAX];
std::vector<SignalInfo> Watchers;
std::list<SignalInfo> Watchers;
bool LinuxSig();
@ -404,6 +404,8 @@ namespace Tasking
int MakeExitCode(int sig);
void InitTrampoline();
const sigset_t nMasks = ToFlag(SIGKILL) |
ToFlag(SIGSTOP) |
ToFlag(SIGCONT) |
@ -502,6 +504,7 @@ namespace Tasking
int SendSignal(int sig, union sigval val = {0});
int WaitAnySignal();
bool HasPendingSignal();
/**
* Wait for a signal

View File

@ -249,6 +249,59 @@ namespace Tasking
return 100 + sig;
}
void Signal::InitTrampoline()
{
if (unlikely(TrampAddr))
return;
PCB *pcb = (PCB *)ctx;
debug("Trampoline not set up yet");
switch (pcb->Info.Compatibility)
{
case Native:
{
debug("%#lx - %#lx",
&_sig_native_trampoline_end,
&_sig_native_trampoline_start);
TrampSz = (size_t)&_sig_native_trampoline_end -
(size_t)&_sig_native_trampoline_start;
TrampAddr = pcb->vma->RequestPages(TO_PAGES(TrampSz), true);
memcpy((void *)TrampAddr,
(void *)&_sig_native_trampoline_start,
TrampSz);
debug("Trampoline at %#lx with size %lld",
TrampAddr, TrampSz);
break;
}
case Linux:
{
debug("%#lx - %#lx",
&_sig_linux_trampoline_end,
&_sig_linux_trampoline_start);
TrampSz = (size_t)&_sig_linux_trampoline_end -
(size_t)&_sig_linux_trampoline_start;
TrampAddr = pcb->vma->RequestPages(TO_PAGES(TrampSz), true);
memcpy((void *)TrampAddr,
(void *)&_sig_linux_trampoline_start,
TrampSz);
debug("Trampoline at %#lx with size %lld",
TrampAddr, TrampSz);
break;
}
case Windows:
{
fixme("Windows compatibility");
break;
}
default:
/* Process not fully initalized. */
return;
}
}
/* ------------------------------------------------------ */
int Signal::AddWatcher(Signal *who, int sig)
@ -306,12 +359,8 @@ namespace Tasking
return false;
/* We don't want to do this in kernel mode */
if (unlikely(tf->cs != GDT_USER_CODE &&
tf->cs != GDT_USER_DATA))
{
// debug("Not user-mode");
if (unlikely(tf->cs != GDT_USER_CODE))
return false;
}
debug("We have %d signals to handle", SignalQueue.size());
@ -367,6 +416,8 @@ namespace Tasking
tf->rip = uint64_t(TrampAddr);
tf->rdi = CTLif(sigI.sig);
tf->rsi = uint64_t(sigI.val.sival_ptr);
assert(TrampAddr != nullptr);
return true;
}
@ -573,50 +624,7 @@ namespace Tasking
return 0;
}
if (unlikely(TrampAddr == nullptr))
{
debug("Trampoline not set up yet");
switch (thisThread->Info.Compatibility)
{
case Native:
{
debug("%#lx - %#lx",
&_sig_native_trampoline_end,
&_sig_native_trampoline_start);
TrampSz = (size_t)&_sig_native_trampoline_end -
(size_t)&_sig_native_trampoline_start;
TrampAddr = pcb->vma->RequestPages(TO_PAGES(TrampSz), true);
memcpy((void *)TrampAddr,
(void *)&_sig_native_trampoline_start,
TrampSz);
debug("Trampoline at %#lx with size %lld",
TrampAddr, TrampSz);
break;
}
case Linux:
{
debug("%#lx - %#lx",
&_sig_linux_trampoline_end,
&_sig_linux_trampoline_start);
TrampSz = (size_t)&_sig_linux_trampoline_end -
(size_t)&_sig_linux_trampoline_start;
TrampAddr = pcb->vma->RequestPages(TO_PAGES(TrampSz), true);
memcpy((void *)TrampAddr,
(void *)&_sig_linux_trampoline_start,
TrampSz);
debug("Trampoline at %#lx with size %lld",
TrampAddr, TrampSz);
break;
}
default:
{
assert(!"Not implemented");
break;
}
}
}
this->InitTrampoline();
debug("Signal %s(%d) completed", sigStr[sig], sig);
if (sigDisp[sig] != SIG_IGN)
@ -661,6 +669,11 @@ namespace Tasking
return -EINTR;
}
bool Signal::HasPendingSignal()
{
return !SignalQueue.empty();
}
int Signal::WaitSignal(int sig, union sigval *val)
{
return 0;