forked from Bananymous/banan-os
Kernel/LibC: Add bareboness signals
You can now call raise() to raise a signal. Signal handlers are not yet supported, but the handling works :)
This commit is contained in:
parent
faf4220b38
commit
dcd4d0daeb
|
@ -75,6 +75,7 @@ if("${BANAN_ARCH}" STREQUAL "x86_64")
|
||||||
arch/x86_64/IDT.cpp
|
arch/x86_64/IDT.cpp
|
||||||
arch/x86_64/interrupts.S
|
arch/x86_64/interrupts.S
|
||||||
arch/x86_64/PageTable.cpp
|
arch/x86_64/PageTable.cpp
|
||||||
|
arch/x86_64/Signal.S
|
||||||
arch/x86_64/Thread.S
|
arch/x86_64/Thread.S
|
||||||
)
|
)
|
||||||
elseif("${BANAN_ARCH}" STREQUAL "i386")
|
elseif("${BANAN_ARCH}" STREQUAL "i386")
|
||||||
|
|
|
@ -11,6 +11,9 @@ extern uint8_t g_kernel_end[];
|
||||||
extern uint8_t g_kernel_execute_start[];
|
extern uint8_t g_kernel_execute_start[];
|
||||||
extern uint8_t g_kernel_execute_end[];
|
extern uint8_t g_kernel_execute_end[];
|
||||||
|
|
||||||
|
extern uint8_t g_userspace_start[];
|
||||||
|
extern uint8_t g_userspace_end[];
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -120,6 +123,14 @@ namespace Kernel
|
||||||
g_kernel_execute_end - g_kernel_execute_start,
|
g_kernel_execute_end - g_kernel_execute_start,
|
||||||
Flags::Execute | Flags::Present
|
Flags::Execute | Flags::Present
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Map userspace memory
|
||||||
|
map_range_at(
|
||||||
|
V2P(g_userspace_start),
|
||||||
|
(vaddr_t)g_userspace_start,
|
||||||
|
g_userspace_end - g_userspace_start,
|
||||||
|
Flags::Execute | Flags::UserSupervisor | Flags::Present
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<PageTable*> PageTable::create_userspace()
|
BAN::ErrorOr<PageTable*> PageTable::create_userspace()
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
.section .userspace, "aw"
|
||||||
|
|
||||||
|
.global signal_trampoline
|
||||||
|
signal_trampoline:
|
||||||
|
pushq %rax
|
||||||
|
pushq %rbx
|
||||||
|
pushq %rcx
|
||||||
|
pushq %rdx
|
||||||
|
pushq %rbp
|
||||||
|
pushq %rdi
|
||||||
|
pushq %rsi
|
||||||
|
pushq %r8
|
||||||
|
pushq %r9
|
||||||
|
pushq %r10
|
||||||
|
pushq %r11
|
||||||
|
pushq %r12
|
||||||
|
pushq %r13
|
||||||
|
pushq %r14
|
||||||
|
pushq %r15
|
||||||
|
|
||||||
|
xchgw %bx, %bx
|
||||||
|
|
||||||
|
movq 128(%rsp), %rdi
|
||||||
|
movq 120(%rsp), %rax
|
||||||
|
call *%rax
|
||||||
|
|
||||||
|
popq %r15
|
||||||
|
popq %r14
|
||||||
|
popq %r13
|
||||||
|
popq %r12
|
||||||
|
popq %r11
|
||||||
|
popq %r10
|
||||||
|
popq %r9
|
||||||
|
popq %r8
|
||||||
|
popq %rsi
|
||||||
|
popq %rdi
|
||||||
|
popq %rbp
|
||||||
|
popq %rdx
|
||||||
|
popq %rcx
|
||||||
|
popq %rbx
|
||||||
|
popq %rax
|
||||||
|
|
||||||
|
addq $16, %rsp
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global test_signal
|
||||||
|
test_signal:
|
||||||
|
movq $99, %rax
|
||||||
|
int $0x80
|
||||||
|
ret
|
|
@ -11,7 +11,13 @@ SECTIONS
|
||||||
{
|
{
|
||||||
g_kernel_execute_start = .;
|
g_kernel_execute_start = .;
|
||||||
*(.multiboot)
|
*(.multiboot)
|
||||||
*(.text)
|
*(.text.*)
|
||||||
|
}
|
||||||
|
.userspace ALIGN(4K) : AT(ADDR(.userspace) - KERNEL_OFFSET)
|
||||||
|
{
|
||||||
|
g_userspace_start = .;
|
||||||
|
*(.userspace)
|
||||||
|
g_userspace_end = .;
|
||||||
}
|
}
|
||||||
.rodata ALIGN(4K) : AT(ADDR(.rodata) - KERNEL_OFFSET)
|
.rodata ALIGN(4K) : AT(ADDR(.rodata) - KERNEL_OFFSET)
|
||||||
{
|
{
|
||||||
|
|
|
@ -100,6 +100,10 @@ namespace Kernel
|
||||||
BAN::ErrorOr<long> sys_alloc(size_t);
|
BAN::ErrorOr<long> sys_alloc(size_t);
|
||||||
BAN::ErrorOr<long> sys_free(void*);
|
BAN::ErrorOr<long> sys_free(void*);
|
||||||
|
|
||||||
|
BAN::ErrorOr<long> sys_signal(int, void (*)(int));
|
||||||
|
BAN::ErrorOr<long> sys_kill(pid_t pid, int signal);
|
||||||
|
BAN::ErrorOr<long> sys_raise(int signal, uintptr_t& return_rsp, uintptr_t& return_rip);
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_termid(char*) const;
|
BAN::ErrorOr<long> sys_termid(char*) const;
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_clock_gettime(clockid_t, timespec*) const;
|
BAN::ErrorOr<long> sys_clock_gettime(clockid_t, timespec*) const;
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/sysmacros.h>
|
#include <sys/sysmacros.h>
|
||||||
|
|
||||||
|
extern "C" void signal_trampoline();
|
||||||
|
extern "C" void test_signal();
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -788,6 +791,27 @@ namespace Kernel
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<long> Process::sys_raise(int signal, uintptr_t& return_rsp, uintptr_t& return_rip)
|
||||||
|
{
|
||||||
|
if (signal < _SIGMIN || signal > _SIGMAX)
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
|
||||||
|
ASSERT(&Process::current() == this);
|
||||||
|
|
||||||
|
LockGuard lock_guard(m_lock);
|
||||||
|
asm volatile("cli");
|
||||||
|
|
||||||
|
uintptr_t* return_rsp_ptr = (uintptr_t*)return_rsp;
|
||||||
|
*--return_rsp_ptr = return_rip;
|
||||||
|
*--return_rsp_ptr = signal;
|
||||||
|
*--return_rsp_ptr = (uintptr_t)test_signal;
|
||||||
|
|
||||||
|
return_rsp = (uintptr_t)return_rsp_ptr;
|
||||||
|
return_rip = (uintptr_t)signal_trampoline;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_setuid(uid_t uid)
|
BAN::ErrorOr<long> Process::sys_setuid(uid_t uid)
|
||||||
{
|
{
|
||||||
if (uid < 0 || uid >= 1'000'000'000)
|
if (uid < 0 || uid >= 1'000'000'000)
|
||||||
|
|
|
@ -140,6 +140,9 @@ namespace Kernel
|
||||||
case SYS_DUP2:
|
case SYS_DUP2:
|
||||||
ret = Process::current().sys_dup2((int)arg1, (int)arg2);
|
ret = Process::current().sys_dup2((int)arg1, (int)arg2);
|
||||||
break;
|
break;
|
||||||
|
case SYS_RAISE:
|
||||||
|
ret = Process::current().sys_raise((int)arg1, interrupt_stack.rsp, interrupt_stack.rip);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
dwarnln("Unknown syscall {}", syscall);
|
dwarnln("Unknown syscall {}", syscall);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -98,8 +98,8 @@ namespace BAN::Formatter
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" uintptr_t g_kernel_start;
|
extern "C" uint8_t g_userspace_start[];
|
||||||
extern "C" uintptr_t g_kernel_end;
|
extern "C" uint8_t g_userspace_end[];
|
||||||
|
|
||||||
static void init2(void*);
|
static void init2(void*);
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ set(LIBC_SOURCES
|
||||||
fcntl.cpp
|
fcntl.cpp
|
||||||
printf_impl.cpp
|
printf_impl.cpp
|
||||||
pwd.cpp
|
pwd.cpp
|
||||||
|
signal.cpp
|
||||||
stdio.cpp
|
stdio.cpp
|
||||||
stdlib.cpp
|
stdlib.cpp
|
||||||
string.cpp
|
string.cpp
|
||||||
|
|
|
@ -74,6 +74,9 @@ struct sigevent
|
||||||
#define SIGRTMIN 29
|
#define SIGRTMIN 29
|
||||||
#define SIGRTMAX (SIGRTMIN+32)
|
#define SIGRTMAX (SIGRTMIN+32)
|
||||||
|
|
||||||
|
#define _SIGMIN SIGABRT
|
||||||
|
#define _SIGMAX SIGRTMAX
|
||||||
|
|
||||||
#define SIG_BLOCK 1
|
#define SIG_BLOCK 1
|
||||||
#define SIG_UNBLOCK 2
|
#define SIG_UNBLOCK 2
|
||||||
#define SIG_SETMASK 3
|
#define SIG_SETMASK 3
|
||||||
|
|
|
@ -41,6 +41,7 @@ __BEGIN_DECLS
|
||||||
#define SYS_CLOCK_GETTIME 34
|
#define SYS_CLOCK_GETTIME 34
|
||||||
#define SYS_PIPE 35
|
#define SYS_PIPE 35
|
||||||
#define SYS_DUP2 36
|
#define SYS_DUP2 36
|
||||||
|
#define SYS_RAISE 37
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int raise(int sig)
|
||||||
|
{
|
||||||
|
return syscall(SYS_RAISE, sig);
|
||||||
|
}
|
|
@ -266,6 +266,12 @@ long syscall(long syscall, ...)
|
||||||
ret = Kernel::syscall(SYS_DUP2, fildes, fildes2);
|
ret = Kernel::syscall(SYS_DUP2, fildes, fildes2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SYS_RAISE:
|
||||||
|
{
|
||||||
|
int signal = va_arg(args, int);
|
||||||
|
ret = Kernel::syscall(SYS_RAISE, signal);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
puts("LibC: Unhandeled syscall");
|
puts("LibC: Unhandeled syscall");
|
||||||
ret = -ENOSYS;
|
ret = -ENOSYS;
|
||||||
|
|
|
@ -260,6 +260,10 @@ int execute_command(BAN::Vector<BAN::String>& args)
|
||||||
while (*current)
|
while (*current)
|
||||||
printf("%s\n", *current++);
|
printf("%s\n", *current++);
|
||||||
}
|
}
|
||||||
|
else if (args.front() == "raise"sv)
|
||||||
|
{
|
||||||
|
raise(SIGSEGV);
|
||||||
|
}
|
||||||
else if (args.front() == "cd"sv)
|
else if (args.front() == "cd"sv)
|
||||||
{
|
{
|
||||||
if (args.size() > 2)
|
if (args.size() > 2)
|
||||||
|
|
Loading…
Reference in New Issue