Compare commits

..

No commits in common. "9d0990e5e89c4fd7534b2960a7fed789ff468f0a" and "84006e1e7793271a0cb8bcbc8e61b342e6fc8293" have entirely different histories.

203 changed files with 2115 additions and 8915 deletions

View File

@ -35,7 +35,7 @@ namespace BAN
constexpr T& front();
Span<T> span() { return Span(m_data, size()); }
Span<const T> span() const { return Span(m_data, size()); }
const Span<T> span() const { return Span(m_data, size()); }
constexpr size_type size() const;

View File

@ -1,90 +0,0 @@
#pragma once
#include <BAN/Iteration.h>
#include <BAN/Swap.h>
#include <BAN/Traits.h>
#include <cstddef>
namespace BAN
{
namespace detail
{
template<typename It, typename Comp>
void heapify_up(It begin, size_t index, Comp comp)
{
size_t parent = (index - 1) / 2;
while (parent < index)
{
if (comp(*(begin + index), *(begin + parent)))
break;
swap(*(begin + parent), *(begin + index));
index = parent;
parent = (index - 1) / 2;
}
}
template<typename It, typename Comp>
void heapify_down(It begin, size_t index, size_t len, Comp comp)
{
for (;;)
{
const size_t lchild = 2 * index + 1;
const size_t rchild = 2 * index + 2;
size_t child = 0;
if (lchild < len && !comp(*(begin + lchild), *(begin + index)))
{
if (rchild < len && !comp(*(begin + rchild), *(begin + lchild)))
child = rchild;
else
child = lchild;
}
else if (rchild < len && !comp(*(begin + rchild), *(begin + index)))
child = rchild;
else
break;
swap(*(begin + child), *(begin + index));
index = child;
}
}
}
template<typename It, typename Comp = less<it_value_type_t<It>>>
void make_heap(It begin, It end, Comp comp = {})
{
const size_t len = distance(begin, end);
if (len <= 1)
return;
size_t index = (len - 2) / 2;
while (index < len)
detail::heapify_down(begin, index--, len, comp);
}
template<typename It, typename Comp = less<it_value_type_t<It>>>
void push_heap(It begin, It end, Comp comp = {})
{
const size_t len = distance(begin, end);
detail::heapify_up(begin, len - 1, comp);
}
template<typename It, typename Comp = less<it_value_type_t<It>>>
void pop_heap(It begin, It end, Comp comp = {})
{
const size_t len = distance(begin, end);
swap(*begin, *(begin + len - 1));
detail::heapify_down(begin, 0, len - 1, comp);
}
template<typename It, typename Comp = less<it_value_type_t<It>>>
void sort_heap(It begin, It end, Comp comp = {})
{
while (begin != end)
pop_heap(begin, end--, comp);
}
}

View File

@ -1,64 +0,0 @@
#pragma once
#include "BAN/Errors.h"
#include <BAN/Vector.h>
#include <BAN/Heap.h>
namespace BAN
{
template<typename T, typename Comp = less<T>>
class PriorityQueue
{
public:
PriorityQueue() = default;
PriorityQueue(Comp comp)
: m_comp(comp)
{ }
ErrorOr<void> push(const T& value)
{
TRY(m_data.push_back(value));
push_heap(m_data.begin(), m_data.end());
return {};
}
ErrorOr<void> push(T&& value)
{
TRY(m_data.push_back(move(value)));
push_heap(m_data.begin(), m_data.end());
return {};
}
template<typename... Args>
ErrorOr<void> emplace(Args&&... args) requires is_constructible_v<T, Args...>
{
TRY(m_data.emplace_back(forward<Args>(args)...));
push_heap(m_data.begin(), m_data.end());
return {};
}
void pop()
{
pop_heap(m_data.begin(), m_data.end());
m_data.pop_back();
}
BAN::ErrorOr<void> reserve(Vector<T>::size_type size)
{
return m_data.reserve(size);
}
T& top() { return m_data.front(); }
const T& top() const { return m_data.front(); }
bool empty() const { return m_data.empty(); }
Vector<T>::size_type size() const { return m_data.size(); }
Vector<T>::size_type capacity() const { return m_data.capacity(); }
private:
Comp m_comp;
Vector<T> m_data;
};
}

View File

@ -1,6 +1,5 @@
#pragma once
#include <BAN/Heap.h>
#include <BAN/Math.h>
#include <BAN/Swap.h>
#include <BAN/Traits.h>
@ -9,7 +8,7 @@
namespace BAN::sort
{
template<typename It, typename Comp = less<it_value_type_t<It>>>
template<typename It, typename Comp = less<typename It::value_type>>
void exchange_sort(It begin, It end, Comp comp = {})
{
for (It lhs = begin; lhs != end; ++lhs)
@ -43,7 +42,7 @@ namespace BAN::sort
}
template<typename It, typename Comp = less<it_value_type_t<It>>>
template<typename It, typename Comp = less<typename It::value_type>>
void quick_sort(It begin, It end, Comp comp = {})
{
if (distance(begin, end) <= 1)
@ -53,14 +52,14 @@ namespace BAN::sort
quick_sort(++mid, end, comp);
}
template<typename It, typename Comp = less<it_value_type_t<It>>>
template<typename It, typename Comp = less<typename It::value_type>>
void insertion_sort(It begin, It end, Comp comp = {})
{
if (distance(begin, end) <= 1)
return;
for (It it1 = next(begin, 1); it1 != end; ++it1)
{
auto x = move(*it1);
typename It::value_type x = move(*it1);
It it2 = it1;
for (; it2 != begin && comp(x, *prev(it2, 1)); --it2)
*it2 = move(*prev(it2, 1));
@ -68,7 +67,83 @@ namespace BAN::sort
}
}
template<typename It, typename Comp = less<it_value_type_t<It>>>
namespace detail
{
template<typename It, typename Comp>
void push_heap(It begin, size_t hole_index, size_t top_index, typename It::value_type value, Comp comp)
{
size_t parent = (hole_index - 1) / 2;
while (hole_index > top_index && comp(*next(begin, parent), value))
{
*next(begin, hole_index) = move(*next(begin, parent));
hole_index = parent;
parent = (hole_index - 1) / 2;
}
*next(begin, hole_index) = move(value);
}
template<typename It, typename Comp>
void adjust_heap(It begin, size_t hole_index, size_t len, typename It::value_type value, Comp comp)
{
const size_t top_index = hole_index;
size_t child = hole_index;
while (child < (len - 1) / 2)
{
child = 2 * (child + 1);
if (comp(*next(begin, child), *next(begin, child - 1)))
child--;
*next(begin, hole_index) = move(*next(begin, child));
hole_index = child;
}
if (len % 2 == 0 && child == (len - 2) / 2)
{
child = 2 * (child + 1);
*next(begin, hole_index) = move(*next(begin, child - 1));
hole_index = child - 1;
}
push_heap(begin, hole_index, top_index, move(value), comp);
}
}
template<typename It, typename Comp = less<typename It::value_type>>
void make_heap(It begin, It end, Comp comp = {})
{
const size_t len = distance(begin, end);
if (len <= 1)
return;
size_t parent = (len - 2) / 2;
while (true)
{
detail::adjust_heap(begin, parent, len, move(*next(begin, parent)), comp);
if (parent == 0)
break;
parent--;
}
}
template<typename It, typename Comp = less<typename It::value_type>>
void sort_heap(It begin, It end, Comp comp = {})
{
const size_t len = distance(begin, end);
if (len <= 1)
return;
size_t last = len;
while (last > 1)
{
last--;
typename It::value_type x = move(*next(begin, last));
*next(begin, last) = move(*begin);
detail::adjust_heap(begin, 0, last, move(x), comp);
}
}
template<typename It, typename Comp = less<typename It::value_type>>
void heap_sort(It begin, It end, Comp comp = {})
{
make_heap(begin, end, comp);
@ -92,7 +167,7 @@ namespace BAN::sort
}
template<typename It, typename Comp = less<it_value_type_t<It>>>
template<typename It, typename Comp = less<typename It::value_type>>
void intro_sort(It begin, It end, Comp comp = {})
{
const size_t len = distance(begin, end);
@ -115,10 +190,10 @@ namespace BAN::sort
}
template<typename It, size_t radix = 256>
requires is_unsigned_v<it_value_type_t<It>> && (radix > 0 && (radix & (radix - 1)) == 0)
requires is_unsigned_v<typename It::value_type> && (radix > 0 && (radix & (radix - 1)) == 0)
BAN::ErrorOr<void> radix_sort(It begin, It end)
{
using value_type = it_value_type_t<It>;
using value_type = typename It::value_type;
const size_t len = distance(begin, end);
if (len <= 1)
@ -156,7 +231,7 @@ namespace BAN::sort
return {};
}
template<typename It, typename Comp = less<it_value_type_t<It>>>
template<typename It, typename Comp = less<typename It::value_type>>
void sort(It begin, It end, Comp comp = {})
{
return intro_sort(begin, end, comp);

View File

@ -139,10 +139,6 @@ namespace BAN
template<typename T> using make_signed_t = typename make_signed<T>::type;
#undef __BAN_TRAITS_MAKE_SIGNED_CV
template<typename T> struct it_value_type { using value_type = T::value_type; };
template<typename T> struct it_value_type<T*> { using value_type = T; };
template<typename T> using it_value_type_t = typename it_value_type<T>::value_type;
template<typename T> struct less { constexpr bool operator()(const T& lhs, const T& rhs) const { return lhs < rhs; } };
template<typename T> struct equal { constexpr bool operator()(const T& lhs, const T& rhs) const { return lhs == rhs; } };
template<typename T> struct greater { constexpr bool operator()(const T& lhs, const T& rhs) const { return lhs > rhs; } };

View File

@ -56,7 +56,7 @@ namespace BAN
bool contains(const T&) const;
Span<T> span() { return Span(m_data, m_size); }
Span<const T> span() const { return Span(m_data, m_size); }
const Span<T> span() const { return Span(m_data, m_size); }
const T& operator[](size_type) const;
T& operator[](size_type);

View File

@ -165,12 +165,6 @@ set(KLIBC_SOURCES
../userspace/libraries/LibC/arch/${BANAN_ARCH}/string.S
)
set(LIBDEFLATE_SOURCE
../userspace/libraries/LibDEFLATE/Compressor.cpp
../userspace/libraries/LibDEFLATE/Decompressor.cpp
../userspace/libraries/LibDEFLATE/HuffmanTree.cpp
)
set(LIBFONT_SOURCES
../userspace/libraries/LibFont/Font.cpp
../userspace/libraries/LibFont/PSF.cpp
@ -181,25 +175,18 @@ set(LIBINPUT_SOURCE
../userspace/libraries/LibInput/KeyEvent.cpp
)
set(LIBQR_SOURCE
../userspace/libraries/LibQR/QRCode.cpp
)
set(KERNEL_SOURCES
${KERNEL_SOURCES}
${BAN_SOURCES}
${KLIBC_SOURCES}
${LIBDEFLATE_SOURCE}
${LIBFONT_SOURCES}
${LIBINPUT_SOURCE}
${LIBQR_SOURCE}
)
add_executable(kernel ${KERNEL_SOURCES})
target_compile_definitions(kernel PRIVATE __is_kernel)
target_compile_definitions(kernel PRIVATE __arch=${BANAN_ARCH})
target_compile_definitions(kernel PRIVATE LIBDEFLATE_AVOID_STACK=1)
target_compile_options(kernel PRIVATE
-O2 -g
@ -253,11 +240,9 @@ add_custom_command(
banan_include_headers(kernel ban)
banan_include_headers(kernel libc)
banan_include_headers(kernel libdeflate)
banan_include_headers(kernel libelf)
banan_include_headers(kernel libfont)
banan_include_headers(kernel libelf)
banan_include_headers(kernel libinput)
banan_include_headers(kernel libqr)
banan_install_headers(kernel)
set_target_properties(kernel PROPERTIES OUTPUT_NAME banan-os.kernel)

View File

@ -2,41 +2,15 @@
// stack contains
// return address
// return stack
// return rflags
// siginfo_t
// signal number
// signal handler
.global signal_trampoline
signal_trampoline:
pushl %esi // gregs
pushl %edi
pushl %edx
pushl %ecx
pushl %ebx
pushl %eax
pushl %ebp
pusha
movl 76(%esp), %eax // return sp
addl $4, %eax // return address
movl 80(%esp), %ebx // return ip
pushl %eax;
pushl %ebx
// FIXME: populate these
xorl %eax, %eax
pushl %eax // stack
pushl %eax
pushl %eax
pushl %eax // sigset
pushl %eax
pushl %eax // link
movl %esp, %edx // ucontext
leal 68(%esp), %esi // siginfo
movl 64(%esp), %edi // signal number
movl 60(%esp), %eax // handlers
movl 40(%esp), %edi
movl 36(%esp), %eax
// align stack to 16 bytes
movl %esp, %ebp
@ -45,9 +19,7 @@ signal_trampoline:
subl $512, %esp
fxsave (%esp)
subl $4, %esp
pushl %edx
pushl %esi
subl $12, %esp
pushl %edi
call *%eax
addl $16, %esp
@ -57,21 +29,9 @@ signal_trampoline:
// restore stack
movl %ebp, %esp
addl $32, %esp
popa
// restore registers
popl %ebp
popl %eax
popl %ebx
popl %ecx
popl %edx
popl %edi
popl %esi
// skip handler, number, siginfo_t
addl $44, %esp
// restore flags
addl $8, %esp
popf
movl (%esp), %esp

View File

@ -1,6 +1,12 @@
// arguments in EAX, EBX, ECX, EDX, ESI, EDI
.global asm_syscall_handler
asm_syscall_handler:
# save segment registers
pushw %ds
pushw %es
pushw %fs
pushw %gs
# save general purpose registers
pushl %ebx
pushl %ecx
@ -12,12 +18,13 @@ asm_syscall_handler:
# align stack
movl %esp, %ebp
andl $-16, %esp
subl $15, %esp
andl $0xFFFFFFF0, %esp
# push arguments
subl $4, %esp
pushl %ebp
addl $24, (%esp)
addl $32, (%esp)
pushl %edi
pushl %esi
pushl %edx
@ -37,15 +44,6 @@ asm_syscall_handler:
movl %ebp, %esp
# restore userspace segments
movw $(0x20 | 3), %bx
movw %bx, %ds
movw %bx, %es
movw $(0x30 | 3), %bx
movw %bx, %fs
movw $(0x38 | 3), %bx
movw %bx, %gs
# restore general purpose registers
popl %ebp
popl %esi
@ -54,6 +52,12 @@ asm_syscall_handler:
popl %ecx
popl %ebx
# restore segment registers
popw %gs
popw %fs
popw %es
popw %ds
iret
.global sys_fork_trampoline

View File

@ -31,6 +31,8 @@ start_kernel_thread:
subl $12, %esp
pushl %edi
call *%esi
addl $16, %esp
.global start_userspace_thread
start_userspace_thread:
@ -39,12 +41,15 @@ start_userspace_thread:
call get_thread_start_sp
movl %eax, %esp
# ds, es = user data
movw $(0x20 | 3), %bx
movw %bx, %ds
movw %bx, %es
# gs = thread local
movw $(0x30 | 3), %bx
movw %bx, %fs
movw $(0x38 | 3), %bx
movw %bx, %gs
# fs = 0
xorw %bx, %bx
movw %bx, %fs
iret

View File

@ -1,7 +1,12 @@
.macro maybe_load_kernel_segments, n
cmpb $0x08, \n(%esp)
je 1f
.macro push_userspace
pushw %gs
pushw %fs
pushw %es
pushw %ds
pushal
.endm
.macro load_kernel_segments
movw $0x10, %ax
movw %ax, %ds
movw %ax, %es
@ -9,26 +14,19 @@
movw $0x28, %ax
movw %ax, %gs
1:
.endm
.macro maybe_load_userspace_segments, n
cmpb $0x08, \n(%esp)
je 1f
movw $(0x20 | 3), %bx
movw %bx, %ds
movw %bx, %es
movw $(0x30 | 3), %bx
movw %bx, %fs
movw $(0x38 | 3), %bx
movw %bx, %gs
1:
.macro pop_userspace
popal
popw %ds
popw %es
popw %fs
popw %gs
.endm
isr_stub:
pushal
maybe_load_kernel_segments 44
push_userspace
load_kernel_segments
cld
movl %cr0, %eax; pushl %eax
@ -36,39 +34,33 @@ isr_stub:
movl %cr3, %eax; pushl %eax
movl %cr4, %eax; pushl %eax
movl 48(%esp), %edi // isr number
movl 52(%esp), %esi // error code
leal 56(%esp), %edx // interrupt stack ptr
movl %esp, %ecx // register ptr
# stack frame for stack trace
leal 56(%esp), %eax
pushl (%eax)
pushl %ebp
movl %esp, %eax // register ptr
leal 64(%esp), %ebx // interrupt stack ptr
movl 60(%esp), %ecx // error code
movl 56(%esp), %edx // isr number
movl %esp, %ebp
andl $-16, %esp
pushl %eax
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
pushl %edi
call cpp_isr_handler
movl %ebp, %esp
addl $24, %esp
addl $16, %esp
maybe_load_userspace_segments 44
popal
pop_userspace
addl $8, %esp
iret
irq_stub:
pushal
maybe_load_kernel_segments 44
push_userspace
load_kernel_segments
cld
movl 32(%esp), %edi # interrupt number
movl 40(%esp), %edi # interrupt number
movl %esp, %ebp
andl $-16, %esp
@ -79,8 +71,7 @@ irq_stub:
movl %ebp, %esp
maybe_load_userspace_segments 44
popal
pop_userspace
addl $8, %esp
iret
@ -108,8 +99,8 @@ asm_yield_handler:
.global asm_ipi_handler
asm_ipi_handler:
pushal
maybe_load_kernel_segments 36
push_userspace
load_kernel_segments
cld
movl %esp, %ebp
@ -119,14 +110,13 @@ asm_ipi_handler:
movl %ebp, %esp
maybe_load_userspace_segments 36
popal
pop_userspace
iret
.global asm_timer_handler
asm_timer_handler:
pushal
maybe_load_kernel_segments 36
push_userspace
load_kernel_segments
cld
movl %esp, %ebp
@ -136,8 +126,7 @@ asm_timer_handler:
movl %ebp, %esp
maybe_load_userspace_segments 36
popal
pop_userspace
iret
.macro isr n

View File

@ -2,48 +2,29 @@
// stack contains
// return address
// return stack
// return rflags
// siginfo_t
// signal number
// signal handler
.global signal_trampoline
signal_trampoline:
pushq %r15 // gregs
pushq %r14
pushq %r13
pushq %r12
pushq %r11
pushq %r10
pushq %r9
pushq %r8
pushq %rsi
pushq %rdi
pushq %rdx
pushq %rax
pushq %rbx
pushq %rcx
pushq %rbx
pushq %rax
pushq %rdx
pushq %rbp
pushq %rdi
pushq %rsi
pushq %r8
pushq %r9
pushq %r10
pushq %r11
pushq %r12
pushq %r13
pushq %r14
pushq %r15
movq 200(%rsp), %rax // return sp
addq $(128 + 8), %rax // red-zone and return address
movq 208(%rsp), %rbx // return ip
pushq %rax;
pushq %rbx
// FIXME: populate these
xorq %rax, %rax
pushq %rax // stack
pushq %rax
pushq %rax
pushq %rax // sigset
pushq %rax // link
movq %rsp, %rdx // ucontext
leaq 192(%rsp), %rsi // siginfo
movq 184(%rsp), %rdi // signal number
movq 176(%rsp), %rax // handler
movq 128(%rsp), %rdi
movq 120(%rsp), %rax
// align stack to 16 bytes
movq %rsp, %rbp
@ -59,32 +40,26 @@ signal_trampoline:
// restore stack
movq %rbp, %rsp
addq $56, %rsp
// restore registers
popq %rbp
popq %rax
popq %rbx
popq %rcx
popq %rdx
popq %rdi
popq %rsi
popq %r8
popq %r9
popq %r10
popq %r11
popq %r12
popq %r13
popq %r14
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
// skip handler, number, siginfo_t
addq $72, %rsp
// restore flags
addq $16, %rsp
popfq
movq (%rsp), %rsp
// return over red-zone and siginfo_t
// return over red-zone
ret $128

View File

@ -2,7 +2,6 @@
// System V ABI: RDI, RSI, RDX, RCX, R8, R9
.global asm_syscall_handler
asm_syscall_handler:
swapgs
pushq %rbx
pushq %rcx
pushq %rdx
@ -43,9 +42,9 @@ asm_syscall_handler:
popq %rdx
popq %rcx
popq %rbx
swapgs
iretq
.global sys_fork_trampoline
sys_fork_trampoline:
pushq %rbx

View File

@ -32,6 +32,4 @@ start_userspace_thread:
call get_thread_start_sp
movq %rax, %rsp
swapgs
iretq

View File

@ -1,12 +1,4 @@
.macro swapgs_if_necessary, n
cmpb $0x08, \n(%rsp)
je 1f
swapgs
1:
.endm
.macro pushaq, n
swapgs_if_necessary \n
.macro pushaq
pushq %rax
pushq %rcx
pushq %rdx
@ -24,7 +16,7 @@
pushq %r15
.endm
.macro popaq, n
.macro popaq
popq %r15
popq %r14
popq %r13
@ -40,11 +32,10 @@
popq %rdx
popq %rcx
popq %rax
swapgs_if_necessary \n
.endm
isr_stub:
pushaq 24
pushaq
cld
movq %cr0, %rax; pushq %rax
movq %cr2, %rax; pushq %rax
@ -58,43 +49,43 @@ isr_stub:
call cpp_isr_handler
addq $32, %rsp
popaq 24
popaq
addq $16, %rsp
iretq
irq_stub:
pushaq 24
pushaq
cld
movq 120(%rsp), %rdi # irq number
call cpp_irq_handler
popaq 24
popaq
addq $16, %rsp
iretq
.global asm_yield_handler
asm_yield_handler:
pushaq 8
pushaq
cld
leaq 120(%rsp), %rdi # interrupt stack ptr
movq %rsp, %rsi # interrupt register ptr
call cpp_yield_handler
popaq 8
popaq
iretq
.global asm_ipi_handler
asm_ipi_handler:
pushaq 8
pushaq
cld
call cpp_ipi_handler
popaq 8
popaq
iretq
.global asm_timer_handler
asm_timer_handler:
pushaq 8
pushaq
cld
call cpp_timer_handler
popaq 8
popaq
iretq
.macro isr n

View File

@ -74,8 +74,6 @@
namespace Debug
{
void dump_stack_trace();
void dump_qr_code();
void putchar(char);
void print_prefix(const char*, int);

View File

@ -10,7 +10,6 @@ namespace Kernel
{
public:
static BAN::ErrorOr<BAN::RefPtr<FramebufferDevice>> create_from_boot_framebuffer();
static BAN::RefPtr<FramebufferDevice> boot_framebuffer();
~FramebufferDevice();
uint32_t width() const { return m_width; }

View File

@ -37,7 +37,6 @@ namespace Kernel
virtual BAN::ErrorOr<void> create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) override;
virtual BAN::ErrorOr<void> create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) override;
virtual BAN::ErrorOr<void> link_inode_impl(BAN::StringView, BAN::RefPtr<Inode>) override;
virtual BAN::ErrorOr<void> rename_inode_impl(BAN::RefPtr<Inode>, BAN::StringView, BAN::StringView) override;
virtual BAN::ErrorOr<void> unlink_impl(BAN::StringView) override;
virtual BAN::ErrorOr<BAN::String> link_target_impl() override;
@ -65,7 +64,6 @@ namespace Kernel
BAN::ErrorOr<BAN::Optional<uint32_t>> fs_block_of_data_block_index(uint32_t data_block_index);
BAN::ErrorOr<void> link_inode_to_directory(Ext2Inode&, BAN::StringView name);
BAN::ErrorOr<void> remove_inode_from_directory(BAN::StringView name, bool cleanup_directory);
BAN::ErrorOr<bool> is_directory_empty();
BAN::ErrorOr<void> cleanup_indirect_block(uint32_t block, uint32_t depth);

View File

@ -97,7 +97,6 @@ namespace Kernel
BAN::ErrorOr<void> create_file(BAN::StringView, mode_t, uid_t, gid_t);
BAN::ErrorOr<void> create_directory(BAN::StringView, mode_t, uid_t, gid_t);
BAN::ErrorOr<void> link_inode(BAN::StringView, BAN::RefPtr<Inode>);
BAN::ErrorOr<void> rename_inode(BAN::RefPtr<Inode>, BAN::StringView, BAN::StringView);
BAN::ErrorOr<void> unlink(BAN::StringView);
// Link API
@ -109,8 +108,8 @@ namespace Kernel
BAN::ErrorOr<void> bind(const sockaddr* address, socklen_t address_len);
BAN::ErrorOr<void> connect(const sockaddr* address, socklen_t address_len);
BAN::ErrorOr<void> listen(int backlog);
BAN::ErrorOr<size_t> sendmsg(const msghdr& message, int flags);
BAN::ErrorOr<size_t> recvmsg(msghdr& message, int flags);
BAN::ErrorOr<size_t> sendto(BAN::ConstByteSpan message, const sockaddr* address, socklen_t address_len);
BAN::ErrorOr<size_t> recvfrom(BAN::ByteSpan buffer, sockaddr* address, socklen_t* address_len);
BAN::ErrorOr<void> getsockname(sockaddr* address, socklen_t* address_len);
BAN::ErrorOr<void> getpeername(sockaddr* address, socklen_t* address_len);
@ -140,13 +139,12 @@ namespace Kernel
protected:
// Directory API
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode_impl(BAN::StringView) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<size_t> list_next_inodes_impl(off_t, struct dirent*, size_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> link_inode_impl(BAN::StringView, BAN::RefPtr<Inode>) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> rename_inode_impl(BAN::RefPtr<Inode>, BAN::StringView, BAN::StringView) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> unlink_impl(BAN::StringView) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode_impl(BAN::StringView) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<size_t> list_next_inodes_impl(off_t, struct dirent*, size_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> link_inode_impl(BAN::StringView, BAN::RefPtr<Inode>) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> unlink_impl(BAN::StringView) { return BAN::Error::from_errno(ENOTSUP); }
// Link API
virtual BAN::ErrorOr<BAN::String> link_target_impl() { return BAN::Error::from_errno(ENOTSUP); }
@ -157,8 +155,8 @@ namespace Kernel
virtual BAN::ErrorOr<void> connect_impl(const sockaddr*, socklen_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> listen_impl(int) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> bind_impl(const sockaddr*, socklen_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<size_t> recvmsg_impl(msghdr&, int) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr&, int) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<size_t> sendto_impl(BAN::ConstByteSpan, const sockaddr*, socklen_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<size_t> recvfrom_impl(BAN::ByteSpan, sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> getsockname_impl(sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); }
@ -189,7 +187,7 @@ namespace Kernel
friend class Epoll;
friend class FileBackedRegion;
friend class OpenFileDescriptorSet;
friend struct SharedFileData;
friend class SharedFileData;
friend class TTY;
};

View File

@ -69,6 +69,10 @@ namespace Kernel
protected:
virtual BAN::ErrorOr<BAN::String> link_target_impl() override;
// You may not write here and this is always non blocking
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override { return BAN::Error::from_errno(EINVAL); }
virtual BAN::ErrorOr<void> truncate_impl(size_t) override { return BAN::Error::from_errno(EINVAL); }
virtual bool can_read_impl() const override { return false; }
virtual bool can_write_impl() const override { return false; }
virtual bool has_error_impl() const override { return false; }
@ -110,54 +114,27 @@ namespace Kernel
class ProcSymlinkInode final : public TmpInode
{
public:
static BAN::ErrorOr<BAN::RefPtr<ProcSymlinkInode>> create_new(BAN::ErrorOr<BAN::String> (*)(void*), void (*)(void*), void* data, TmpFileSystem&, mode_t, uid_t, gid_t);
~ProcSymlinkInode();
static BAN::ErrorOr<BAN::RefPtr<ProcSymlinkInode>> create_new(BAN::ErrorOr<BAN::String> (*)(void*), void* data, TmpFileSystem&, mode_t, uid_t, gid_t);
~ProcSymlinkInode() = default;
protected:
virtual BAN::ErrorOr<BAN::String> link_target_impl() override;
// You may not write here and this is always non blocking
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override { return BAN::Error::from_errno(EINVAL); }
virtual BAN::ErrorOr<void> truncate_impl(size_t) override { return BAN::Error::from_errno(EINVAL); }
virtual bool can_read_impl() const override { return false; }
virtual bool can_write_impl() const override { return false; }
virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private:
ProcSymlinkInode(BAN::ErrorOr<BAN::String> (*callback)(void*), void (*destructor)(void*), void* data, TmpFileSystem&, const TmpInodeInfo&);
ProcSymlinkInode(BAN::ErrorOr<BAN::String> (*callback)(void*), void* data, TmpFileSystem&, const TmpInodeInfo&);
private:
BAN::ErrorOr<BAN::String> (*m_callback)(void*);
void (*m_destructor)(void*);
void* m_data;
};
class ProcFDDirectoryInode final : public TmpInode
{
public:
static BAN::ErrorOr<BAN::RefPtr<ProcFDDirectoryInode>> create_new(Process&, TmpFileSystem&, mode_t);
~ProcFDDirectoryInode() = default;
virtual uid_t uid() const override { return m_process.credentials().ruid(); }
virtual gid_t gid() const override { return m_process.credentials().rgid(); }
protected:
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode_impl(BAN::StringView) override;
virtual BAN::ErrorOr<size_t> list_next_inodes_impl(off_t, struct dirent*, size_t) override;
virtual BAN::ErrorOr<void> create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) override { return BAN::Error::from_errno(EPERM); }
virtual BAN::ErrorOr<void> create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) override { return BAN::Error::from_errno(EPERM); }
virtual BAN::ErrorOr<void> link_inode_impl(BAN::StringView, BAN::RefPtr<Inode>) override { return BAN::Error::from_errno(EPERM); }
virtual BAN::ErrorOr<void> rename_inode_impl(BAN::RefPtr<Inode>, BAN::StringView, BAN::StringView) override { return BAN::Error::from_errno(EPERM); }
virtual BAN::ErrorOr<void> unlink_impl(BAN::StringView) override { return BAN::Error::from_errno(EPERM); }
virtual bool can_read_impl() const override { return false; }
virtual bool can_write_impl() const override { return false; }
virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private:
ProcFDDirectoryInode(Process&, TmpFileSystem&, const TmpInodeInfo&);
private:
Process& m_process;
};
}

View File

@ -51,6 +51,8 @@ namespace Kernel
: m_info(info)
{}
BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan buffer) override { return recvfrom_impl(buffer, nullptr, nullptr); }
BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan buffer) override { return sendto_impl(buffer, nullptr, 0); }
BAN::ErrorOr<void> fsync_impl() final override { return {}; }
private:

View File

@ -157,7 +157,6 @@ namespace Kernel
virtual BAN::ErrorOr<void> create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) override final;
virtual BAN::ErrorOr<void> create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) override final;
virtual BAN::ErrorOr<void> link_inode_impl(BAN::StringView, BAN::RefPtr<Inode>) override final;
virtual BAN::ErrorOr<void> rename_inode_impl(BAN::RefPtr<Inode>, BAN::StringView, BAN::StringView) override final;
virtual BAN::ErrorOr<void> unlink_impl(BAN::StringView) override;
virtual bool can_read_impl() const override { return false; }
@ -169,8 +168,6 @@ namespace Kernel
template<TmpFuncs::for_each_valid_entry_callback F>
void for_each_valid_entry(F callback);
BAN::ErrorOr<void> unlink_inode(BAN::StringView, bool cleanup);
friend class TmpInode;
};

View File

@ -129,8 +129,7 @@ namespace Kernel
}
#if ARCH(i686)
void set_fsbase(uintptr_t addr);
void set_gsbase(uintptr_t addr);
void set_tls(uintptr_t addr);
#endif
private:
@ -154,8 +153,8 @@ namespace Kernel
BAN::Array<SegmentDescriptor, 7> m_gdt; // null, kernel code, kernel data, user code, user data, tss low, tss high
static constexpr uint16_t m_tss_offset = 0x28;
#elif ARCH(i686)
BAN::Array<SegmentDescriptor, 9> m_gdt; // null, kernel code, kernel data, user code, user data, processor data, fsbase, gsbase, tss
static constexpr uint16_t m_tss_offset = 0x40;
BAN::Array<SegmentDescriptor, 8> m_gdt; // null, kernel code, kernel data, user code, user data, processor data, tls, tss
static constexpr uint16_t m_tss_offset = 0x38;
#endif
TaskStateSegment m_tss;
const GDTR m_gdtr {

View File

@ -33,7 +33,6 @@ namespace Kernel
BAN::ErrorOr<void> msync(vaddr_t, size_t, int) override;
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override;
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> split(size_t offset) override;
protected:
BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr, bool wants_write) override;

View File

@ -15,7 +15,6 @@ namespace Kernel
~MemoryBackedRegion();
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override;
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> split(size_t offset) override;
BAN::ErrorOr<void> msync(vaddr_t, size_t, int) override { return {}; }

View File

@ -33,7 +33,6 @@ namespace Kernel
bool contains(vaddr_t address) const;
bool contains_fully(vaddr_t address, size_t size) const;
bool overlaps(vaddr_t address, size_t size) const;
bool is_contained_by(vaddr_t address, size_t size) const;
bool writable() const { return m_flags & PageTable::Flags::ReadWrite; }
@ -60,7 +59,6 @@ namespace Kernel
BAN::ErrorOr<bool> allocate_page_containing(vaddr_t address, bool wants_write);
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) = 0;
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> split(size_t offset) = 0;
protected:
MemoryRegion(PageTable&, size_t size, Type type, PageTable::flags_t flags, int status_flags);
@ -70,7 +68,7 @@ namespace Kernel
protected:
PageTable& m_page_table;
size_t m_size { 0 };
const size_t m_size;
const Type m_type;
PageTable::flags_t m_flags;
const int m_status_flags;

View File

@ -58,7 +58,6 @@ namespace Kernel
static BAN::ErrorOr<BAN::UniqPtr<SharedMemoryObject>> create(BAN::RefPtr<SharedMemoryObjectManager::Object>, PageTable&, AddressRange);
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override;
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> split(size_t offset) override;
BAN::ErrorOr<void> msync(vaddr_t, size_t, int) override { return {}; }

View File

@ -60,8 +60,8 @@ namespace Kernel
virtual BAN::ErrorOr<void> connect_impl(const sockaddr*, socklen_t) override;
virtual BAN::ErrorOr<void> listen_impl(int) override;
virtual BAN::ErrorOr<void> bind_impl(const sockaddr*, socklen_t) override;
virtual BAN::ErrorOr<size_t> recvmsg_impl(msghdr& message, int flags) override;
virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr& message, int flags) override;
virtual BAN::ErrorOr<size_t> sendto_impl(BAN::ConstByteSpan, const sockaddr*, socklen_t) override;
virtual BAN::ErrorOr<size_t> recvfrom_impl(BAN::ByteSpan, sockaddr*, socklen_t*) override;
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override;
virtual BAN::ErrorOr<long> ioctl_impl(int, void*) override;

View File

@ -33,10 +33,9 @@ namespace Kernel
protected:
virtual void receive_packet(BAN::ConstByteSpan, const sockaddr* sender, socklen_t sender_len) override;
virtual BAN::ErrorOr<void> connect_impl(const sockaddr*, socklen_t) override;
virtual BAN::ErrorOr<void> bind_impl(const sockaddr* address, socklen_t address_len) override;
virtual BAN::ErrorOr<size_t> recvmsg_impl(msghdr& message, int flags) override;
virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr& message, int flags) override;
virtual BAN::ErrorOr<size_t> sendto_impl(BAN::ConstByteSpan message, const sockaddr* address, socklen_t address_len) override;
virtual BAN::ErrorOr<size_t> recvfrom_impl(BAN::ByteSpan buffer, sockaddr* address, socklen_t* address_len) override;
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override { return BAN::Error::from_errno(ENOTCONN); }
virtual BAN::ErrorOr<long> ioctl_impl(int, void*) override;
@ -64,9 +63,6 @@ namespace Kernel
SpinLock m_packet_lock;
ThreadBlocker m_packet_thread_blocker;
sockaddr_storage m_peer_address {};
socklen_t m_peer_address_len { 0 };
friend class BAN::RefPtr<UDPSocket>;
};

View File

@ -7,7 +7,6 @@
#include <kernel/FS/TmpFS/Inode.h>
#include <kernel/FS/VirtualFileSystem.h>
#include <kernel/Lock/SpinLock.h>
#include <kernel/OpenFileDescriptorSet.h>
namespace Kernel
{
@ -17,9 +16,6 @@ namespace Kernel
BAN_NON_COPYABLE(UnixDomainSocket);
BAN_NON_MOVABLE(UnixDomainSocket);
public:
using FDWrapper = OpenFileDescriptorSet::FDWrapper;
public:
static BAN::ErrorOr<BAN::RefPtr<UnixDomainSocket>> create(Socket::Type, const Socket::Info&);
BAN::ErrorOr<void> make_socket_pair(UnixDomainSocket&);
@ -29,8 +25,8 @@ namespace Kernel
virtual BAN::ErrorOr<void> connect_impl(const sockaddr*, socklen_t) override;
virtual BAN::ErrorOr<void> listen_impl(int) override;
virtual BAN::ErrorOr<void> bind_impl(const sockaddr*, socklen_t) override;
virtual BAN::ErrorOr<size_t> recvmsg_impl(msghdr& message, int flags) override;
virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr& message, int flags) override;
virtual BAN::ErrorOr<size_t> sendto_impl(BAN::ConstByteSpan, const sockaddr*, socklen_t) override;
virtual BAN::ErrorOr<size_t> recvfrom_impl(BAN::ByteSpan, sockaddr*, socklen_t*) override;
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override;
virtual bool can_read_impl() const override;
@ -42,6 +38,8 @@ namespace Kernel
UnixDomainSocket(Socket::Type, const Socket::Info&);
~UnixDomainSocket();
BAN::ErrorOr<void> add_packet(BAN::ConstByteSpan);
bool is_bound() const { return !m_bound_file.canonical_path.empty(); }
bool is_bound_to_unused() const { return !m_bound_file.inode; }
@ -56,7 +54,7 @@ namespace Kernel
BAN::WeakPtr<UnixDomainSocket> connection;
BAN::Queue<BAN::RefPtr<UnixDomainSocket>> pending_connections;
ThreadBlocker pending_thread_blocker;
Mutex pending_lock;
SpinLock pending_lock;
};
struct ConnectionlessInfo
@ -64,26 +62,17 @@ namespace Kernel
BAN::String peer_address;
};
struct PacketInfo
{
size_t size;
BAN::Vector<FDWrapper> fds;
BAN::Optional<struct ucred> ucred;
};
BAN::ErrorOr<void> add_packet(const msghdr&, PacketInfo&&);
private:
const Socket::Type m_socket_type;
VirtualFileSystem::File m_bound_file;
BAN::Variant<ConnectionInfo, ConnectionlessInfo> m_info;
BAN::CircularQueue<PacketInfo, 512> m_packet_infos;
size_t m_packet_size_total { 0 };
BAN::UniqPtr<VirtualRange> m_packet_buffer;
Mutex m_packet_lock;
ThreadBlocker m_packet_thread_blocker;
BAN::CircularQueue<size_t, 128> m_packet_sizes;
size_t m_packet_size_total { 0 };
BAN::UniqPtr<VirtualRange> m_packet_buffer;
SpinLock m_packet_lock;
ThreadBlocker m_packet_thread_blocker;
friend class BAN::RefPtr<UnixDomainSocket>;
};

View File

@ -33,7 +33,7 @@ namespace Kernel
BAN::ErrorOr<int> dup2(int, int);
BAN::ErrorOr<int> fcntl(int fd, int cmd, uintptr_t extra);
BAN::ErrorOr<int> fcntl(int fd, int cmd, int extra);
BAN::ErrorOr<off_t> seek(int fd, off_t offset, int whence);
BAN::ErrorOr<off_t> tell(int) const;
@ -51,8 +51,8 @@ namespace Kernel
BAN::ErrorOr<size_t> read_dir_entries(int fd, struct dirent* list, size_t list_len);
BAN::ErrorOr<size_t> recvmsg(int socket, msghdr& message, int flags);
BAN::ErrorOr<size_t> sendmsg(int socket, const msghdr& message, int flags);
BAN::ErrorOr<size_t> recvfrom(int fd, BAN::ByteSpan buffer, sockaddr* address, socklen_t* address_len);
BAN::ErrorOr<size_t> sendto(int fd, BAN::ConstByteSpan buffer, const sockaddr* address, socklen_t address_len);
BAN::ErrorOr<VirtualFileSystem::File> file_of(int) const;
BAN::ErrorOr<BAN::String> path_of(int) const;
@ -74,8 +74,8 @@ namespace Kernel
struct flock_t
{
bool locked { false };
bool shared { false };
bool locked;
bool shared;
ThreadBlocker thread_blocker;
BAN::HashSet<pid_t> lockers;
};
@ -109,32 +109,6 @@ namespace Kernel
BAN::ErrorOr<int> get_free_fd() const;
BAN::ErrorOr<void> get_free_fd_pair(int fds[2]) const;
public:
class FDWrapper
{
public:
FDWrapper(BAN::RefPtr<OpenFileDescription>);
FDWrapper(const FDWrapper& other) { *this = other; }
FDWrapper(FDWrapper&& other) { *this = BAN::move(other); }
~FDWrapper();
FDWrapper& operator=(const FDWrapper&);
FDWrapper& operator=(FDWrapper&&);
int fd() const { return m_fd; }
void clear();
private:
BAN::RefPtr<OpenFileDescription> m_description;
int m_fd { -1 };
friend class OpenFileDescriptorSet;
};
BAN::ErrorOr<FDWrapper> get_fd_wrapper(int fd);
size_t open_all_fd_wrappers(BAN::Span<FDWrapper> fd_wrappers);
private:
const Credentials& m_credentials;
mutable Mutex m_mutex;

View File

@ -19,26 +19,15 @@ namespace Kernel
asm volatile("cli");
const bool had_debug_lock = Debug::s_debug_lock.current_processor_has_lock();
bool first_panic = false;
derrorln("Kernel panic at {}", location);
if (had_debug_lock)
derrorln(" while having debug lock...");
derrorln(message, BAN::forward<Args>(args)...);
if (!g_paniced)
{
SpinLockGuard _(Debug::s_debug_lock);
derrorln("Kernel panic at {}", location);
if (had_debug_lock)
derrorln(" while having debug lock...");
derrorln(message, BAN::forward<Args>(args)...);
if (!g_paniced)
{
Debug::dump_stack_trace();
g_paniced = true;
first_panic = true;
}
g_paniced = true;
Debug::dump_stack_trace();
}
if (first_panic)
Debug::dump_qr_code();
asm volatile("ud2");
__builtin_unreachable();
}

View File

@ -109,9 +109,9 @@ namespace Kernel
BAN::ErrorOr<long> sys_access(const char* path, int amode);
BAN::ErrorOr<long> sys_create_dir(const char*, mode_t);
BAN::ErrorOr<long> sys_hardlinkat(int fd1, const char* path1, int fd2, const char* path2, int flag);
BAN::ErrorOr<long> sys_renameat(int oldfd, const char* old, int newfd, const char* _new);
BAN::ErrorOr<long> sys_unlinkat(int fd, const char* path, int flag);
BAN::ErrorOr<long> sys_readlinkat(int fd, const char* path, char* buffer, size_t bufsize);
BAN::ErrorOr<long> sys_symlinkat(const char* path1, int fd, const char* path2);
BAN::ErrorOr<long> sys_flock(int fd, int op);
@ -134,8 +134,8 @@ namespace Kernel
BAN::ErrorOr<long> sys_bind(int socket, const sockaddr* address, socklen_t address_len);
BAN::ErrorOr<long> sys_connect(int socket, const sockaddr* address, socklen_t address_len);
BAN::ErrorOr<long> sys_listen(int socket, int backlog);
BAN::ErrorOr<long> sys_recvmsg(int socket, msghdr* message, int flags);
BAN::ErrorOr<long> sys_sendmsg(int socket, const msghdr* message, int flags);
BAN::ErrorOr<long> sys_sendto(const sys_sendto_t*);
BAN::ErrorOr<long> sys_recvfrom(sys_recvfrom_t*);
BAN::ErrorOr<long> sys_ioctl(int fildes, int request, void* arg);
@ -149,7 +149,7 @@ namespace Kernel
BAN::ErrorOr<long> sys_pipe(int fildes[2]);
BAN::ErrorOr<long> sys_dup2(int fildes, int fildes2);
BAN::ErrorOr<long> sys_fcntl(int fildes, int cmd, uintptr_t extra);
BAN::ErrorOr<long> sys_fcntl(int fildes, int cmd, int extra);
BAN::ErrorOr<long> sys_seek(int fd, off_t offset, int whence);
BAN::ErrorOr<long> sys_tell(int fd);
@ -172,7 +172,6 @@ namespace Kernel
BAN::ErrorOr<long> sys_readdir(int fd, struct dirent* list, size_t list_len);
BAN::ErrorOr<BAN::Vector<BAN::UniqPtr<MemoryRegion>>> split_memory_region(BAN::UniqPtr<MemoryRegion>&& region, vaddr_t base, size_t length);
BAN::ErrorOr<long> sys_mmap(const sys_mmap_t*);
BAN::ErrorOr<long> sys_munmap(void* addr, size_t len);
BAN::ErrorOr<long> sys_mprotect(void* addr, size_t len, int prot);
@ -192,7 +191,7 @@ namespace Kernel
void set_stopped(bool stopped, int signal);
void wait_while_stopped();
static BAN::ErrorOr<void> kill(pid_t pid, int signal, const siginfo_t& = {});
static BAN::ErrorOr<void> kill(pid_t pid, int signal);
BAN::ErrorOr<long> sys_kill(pid_t pid, int signal);
BAN::ErrorOr<long> sys_sigaction(int signal, const struct sigaction* act, struct sigaction* oact);
BAN::ErrorOr<long> sys_sigpending(sigset_t* set);
@ -203,12 +202,8 @@ namespace Kernel
BAN::ErrorOr<long> sys_futex(int op, const uint32_t* addr, uint32_t val, const timespec* abstime);
BAN::ErrorOr<long> sys_yield();
BAN::ErrorOr<long> sys_set_fsbase(void*);
BAN::ErrorOr<long> sys_get_fsbase();
BAN::ErrorOr<long> sys_set_gsbase(void*);
BAN::ErrorOr<long> sys_get_gsbase();
BAN::ErrorOr<long> sys_set_tls(void*);
BAN::ErrorOr<long> sys_get_tls();
BAN::ErrorOr<long> sys_pthread_create(const pthread_attr_t* attr, void (*entry)(void*), void* arg);
BAN::ErrorOr<long> sys_pthread_exit(void* value);
BAN::ErrorOr<long> sys_pthread_join(pthread_t thread, void** value);
@ -233,8 +228,7 @@ namespace Kernel
size_t proc_meminfo(off_t offset, BAN::ByteSpan) const;
size_t proc_cmdline(off_t offset, BAN::ByteSpan) const;
size_t proc_environ(off_t offset, BAN::ByteSpan) const;
BAN::ErrorOr<BAN::String> proc_cwd() const;
BAN::ErrorOr<BAN::String> proc_exe() const;
BAN::ErrorOr<BAN::String> proc_executable() const;
BAN::StringView executable() const { return m_executable; }
@ -246,8 +240,6 @@ namespace Kernel
// FIXME: remove this API
BAN::ErrorOr<BAN::String> absolute_path_of(BAN::StringView) const;
OpenFileDescriptorSet& open_file_descriptor_set() { return m_open_file_descriptors; }
// ONLY CALLED BY TIMER INTERRUPT
static void update_alarm_queue();
@ -271,17 +263,12 @@ namespace Kernel
BAN::StringView file_name;
};
// Adds new region to the sorted array of mapped regions
BAN::ErrorOr<void> add_mapped_region(BAN::UniqPtr<MemoryRegion>&&);
// If address is contained by a region, returns the index of that.
// Otherwise returns the address of the first region after this address.
size_t find_mapped_region(vaddr_t) const;
BAN::ErrorOr<VirtualFileSystem::File> find_file(int fd, const char* path, int flags) const;
BAN::ErrorOr<FileParent> find_parent_file(int fd, const char* path, int flags) const;
BAN::ErrorOr<VirtualFileSystem::File> find_relative_parent(int fd, const char* path) const;
BAN::ErrorOr<void> validate_string_access(const char*);
BAN::ErrorOr<void> validate_pointer_access_check(const void*, size_t, bool needs_write);
BAN::ErrorOr<void> validate_pointer_access(const void*, size_t, bool needs_write);
BAN::ErrorOr<MemoryRegion*> validate_and_pin_pointer_access(const void*, size_t, bool needs_write);
@ -291,7 +278,7 @@ namespace Kernel
return m_signal_pending_mask;
}
void add_pending_signal(uint8_t signal, const siginfo_t& info)
void add_pending_signal(uint8_t signal)
{
ASSERT(signal >= _SIGMIN);
ASSERT(signal <= _SIGMAX);
@ -303,7 +290,6 @@ namespace Kernel
if (handler == SIG_DFL && (signal == SIGCHLD || signal == SIGURG))
return;
m_signal_pending_mask |= 1ull << signal;
m_signal_infos[signal] = info;
}
void remove_pending_signal(uint8_t signal)
@ -356,7 +342,6 @@ namespace Kernel
uint64_t m_alarm_wake_time_ns { 0 };
mutable SpinLock m_signal_lock;
siginfo_t m_signal_infos[_SIGMAX + 1] { };
struct sigaction m_signal_handlers[_SIGMAX + 1] { };
uint64_t m_signal_pending_mask { 0 };

View File

@ -112,9 +112,7 @@ namespace Kernel
static void send_smp_message(ProcessorID, const SMPMessage&, bool send_ipi = true);
static void broadcast_smp_message(const SMPMessage&);
static void load_segments();
static void load_fsbase();
static void load_gsbase();
static void load_tls();
private:
Processor() = default;

View File

@ -59,8 +59,8 @@ namespace Kernel
bool can_add_signal_to_execute() const;
bool will_execute_signal() const;
// Returns true if handled signal had SA_RESTART
bool handle_signal(int signal = 0, const siginfo_t& signal_info = {});
void add_signal(int signal, const siginfo_t& info);
bool handle_signal(int signal = 0);
void add_signal(int signal);
void set_suspend_signal_mask(uint64_t sigmask);
static bool is_stopping_signal(int signal);
@ -122,10 +122,8 @@ namespace Kernel
void set_cpu_time_start();
void set_cpu_time_stop();
void set_fsbase(vaddr_t base) { m_fsbase = base; }
vaddr_t get_fsbase() const { return m_fsbase; }
void set_gsbase(vaddr_t base) { m_gsbase = base; }
vaddr_t get_gsbase() const { return m_gsbase; }
void set_tls(vaddr_t tls) { m_tls = tls; }
vaddr_t get_tls() const { return m_tls; }
size_t virtual_page_count() const { return (m_kernel_stack ? (m_kernel_stack->size() / PAGE_SIZE) : 0) + (m_userspace_stack ? (m_userspace_stack->size() / PAGE_SIZE) : 0); }
size_t physical_page_count() const { return virtual_page_count(); }
@ -166,15 +164,13 @@ namespace Kernel
bool m_is_userspace { false };
bool m_delete_process { false };
vaddr_t m_fsbase { 0 };
vaddr_t m_gsbase { 0 };
vaddr_t m_tls { 0 };
SchedulerQueue::Node* m_scheduler_node { nullptr };
InterruptStack m_interrupt_stack { };
InterruptRegisters m_interrupt_registers { };
siginfo_t m_signal_infos[_SIGMAX + 1] { };
uint64_t m_signal_pending_mask { 0 };
uint64_t m_signal_block_mask { 0 };
BAN::Optional<uint64_t> m_signal_suspend_mask;

View File

@ -0,0 +1,7 @@
#pragma once
#include <BAN/Formatter.h>
#include <kernel/Terminal/TTY.h>
#define kprint(...) BAN::Formatter::print(Kernel::TTY::putchar_current, __VA_ARGS__)
#define kprintln(...) BAN::Formatter::println(Kernel::TTY::putchar_current, __VA_ARGS__)

View File

@ -856,7 +856,7 @@ acpi_release_global_lock:
};
// TODO: EC can also reside in memory space
auto crs_buffer = BAN::ConstByteSpan { crs.as.str_buf->bytes, static_cast<size_t>(crs.as.str_buf->size) };
auto crs_buffer = BAN::ConstByteSpan { crs.as.str_buf->bytes, crs.as.str_buf->size };
const auto data_port = TRY(extract_io_port(crs_buffer));
const auto command_port = TRY(extract_io_port(crs_buffer));

View File

@ -56,7 +56,7 @@ namespace Kernel::ACPI
EmbeddedController::~EmbeddedController()
{
if (m_thread)
m_thread->add_signal(SIGKILL, {});
m_thread->add_signal(SIGKILL);
m_thread = nullptr;
}

View File

@ -1,5 +1,4 @@
#include <kernel/Debug.h>
#include <kernel/Device/FramebufferDevice.h>
#include <kernel/InterruptController.h>
#include <kernel/Lock/SpinLock.h>
#include <kernel/Memory/PageTable.h>
@ -7,9 +6,6 @@
#include <kernel/Terminal/TTY.h>
#include <kernel/Timer/Timer.h>
#include <LibDEFLATE/Compressor.h>
#include <LibQR/QRCode.h>
#include <ctype.h>
bool g_disable_debug = false;
@ -19,15 +15,6 @@ namespace Debug
Kernel::RecursiveSpinLock s_debug_lock;
static constexpr char s_panic_url_prefix[] = "https://bananymous.com/panic#";
static constexpr size_t s_qr_code_max_capacity { 2953 };
static bool s_qr_code_shown { false };
static char s_debug_buffer[16 * 1024] {};
static size_t s_debug_buffer_tail { 0 };
static size_t s_debug_buffer_size { 0 };
static uint8_t s_debug_ansi_state { 0 };
void dump_stack_trace()
{
using namespace Kernel;
@ -85,203 +72,17 @@ namespace Debug
BAN::Formatter::print(Debug::putchar, "\e[m");
}
static void queue_debug_buffer(char ch)
{
switch (s_debug_ansi_state)
{
case 1:
if (ch == '[')
{
s_debug_ansi_state = 2;
break;
}
s_debug_ansi_state = 0;
[[fallthrough]];
case 0:
if (ch == '\e')
{
s_debug_ansi_state = 1;
break;
}
if (!isprint(ch) && ch != '\n')
break;
s_debug_buffer[(s_debug_buffer_tail + s_debug_buffer_size) % sizeof(s_debug_buffer)] = ch;
if (s_debug_buffer_size < sizeof(s_debug_buffer))
s_debug_buffer_size++;
else
s_debug_buffer_tail = (s_debug_buffer_tail + 1) % sizeof(s_debug_buffer);
break;
case 2:
if (isalpha(ch))
s_debug_ansi_state = 0;
break;
}
}
static void reverse(char* first, char* last)
{
const size_t len = last - first;
for (size_t i = 0; i < len / 2; i++)
BAN::swap(first[i], first[len - i - 1]);
}
static void rotate(char* first, char* middle, char* last)
{
reverse(first, middle);
reverse(middle, last);
reverse(first, last);
}
static BAN::ErrorOr<BAN::Vector<uint8_t>> compress_kernel_logs()
{
constexpr size_t max_size = ((s_qr_code_max_capacity + 3) / 4 * 3) - sizeof(s_panic_url_prefix);
BAN::Vector<uint8_t> result;
size_t l = 0, r = s_debug_buffer_size;
while (l + 50 < r)
{
const size_t middle = (l + r) / 2;
const uint8_t* base = reinterpret_cast<const uint8_t*>(s_debug_buffer) + s_debug_buffer_size - middle;
auto compressed = TRY(LibDEFLATE::Compressor({ base, middle }, LibDEFLATE::StreamType::Zlib).compress());
if (compressed.size() > max_size)
r = middle;
else
{
l = middle;
result = BAN::move(compressed);
}
}
return result;
}
void dump_qr_code()
{
ASSERT(Kernel::g_paniced);
auto boot_framebuffer = Kernel::FramebufferDevice::boot_framebuffer();
if (!boot_framebuffer)
{
derrorln("No boot framebuffer, not generating QR code");
return;
}
if (boot_framebuffer->width() < 177 + 8 || boot_framebuffer->height() < 177 + 8)
{
derrorln("Boot framebuffer is too small for a qr code");
return;
}
// rotate logs to start from index 0 and be contiguous
rotate(s_debug_buffer, s_debug_buffer + s_debug_buffer_tail, s_debug_buffer + sizeof(s_debug_buffer));
auto compressed_or_error = compress_kernel_logs();
if (compressed_or_error.is_error())
{
// TODO: send uncompressed logs?
derrorln("Failed to compress kernel logs: {}", compressed_or_error.error());
return;
}
auto compressed = compressed_or_error.release_value();
static uint8_t qr_code_data[s_qr_code_max_capacity];
size_t qr_code_data_len = 0;
for (size_t i = 0; s_panic_url_prefix[i]; i++)
qr_code_data[qr_code_data_len++] = s_panic_url_prefix[i];
constexpr char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
for (size_t i = 0; i < compressed.size() / 3; i++)
{
const uint32_t bits =
((compressed[3 * i + 0]) << 16) |
((compressed[3 * i + 1]) << 8) |
((compressed[3 * i + 2]) << 0);
qr_code_data[qr_code_data_len++] = alphabet[(bits >> 18) & 0x3F];
qr_code_data[qr_code_data_len++] = alphabet[(bits >> 12) & 0x3F];
qr_code_data[qr_code_data_len++] = alphabet[(bits >> 6) & 0x3F];
qr_code_data[qr_code_data_len++] = alphabet[(bits >> 0) & 0x3F];
}
switch (compressed.size() % 3)
{
case 0:
break;
case 1:
{
const uint16_t bits =
(compressed[compressed.size() - 1] << 4);
qr_code_data[qr_code_data_len++] = alphabet[(bits >> 6) & 0x3F];
qr_code_data[qr_code_data_len++] = alphabet[(bits >> 0) & 0x3F];
break;
}
case 2:
{
const uint32_t bits =
(compressed[compressed.size() - 2] << 10) |
(compressed[compressed.size() - 1] << 2);
qr_code_data[qr_code_data_len++] = alphabet[(bits >> 12) & 0x3F];
qr_code_data[qr_code_data_len++] = alphabet[(bits >> 6) & 0x3F];
qr_code_data[qr_code_data_len++] = alphabet[(bits >> 0) & 0x3F];
break;
}
}
auto qr_or_error = LibQR::QRCode::generate({ qr_code_data, qr_code_data_len });
if (qr_or_error.is_error())
{
derrorln("Failed to generate QR code");
return;
}
auto qr_code = qr_or_error.release_value();
// after this point no more logs are printed to framebuffer
s_qr_code_shown = true;
const size_t min_framebuffer_dimension = BAN::Math::min(boot_framebuffer->width(), boot_framebuffer->height());
const size_t module_size = min_framebuffer_dimension / (qr_code.size() + 8);
for (size_t y = 0; y < (qr_code.size() + 8) * module_size; y++)
for (size_t x = 0; x < (qr_code.size() + 8) * module_size; x++)
boot_framebuffer->set_pixel(x, y, 0xFFFFFF);
for (size_t y = 0; y < qr_code.size(); y++)
{
for (size_t x = 0; x < qr_code.size(); x++)
{
if (!qr_code.get(x, y))
continue;
for (size_t i = 0; i < module_size; i++)
for (size_t j = 0; j < module_size; j++)
boot_framebuffer->set_pixel((x + 4) * module_size + j, (y + 4) * module_size + i, 0x000000);
}
}
boot_framebuffer->sync_pixels_rectangle(0, 0, (qr_code.size() + 8) * module_size, (qr_code.size() + 8) * module_size);
}
void putchar(char ch)
{
using namespace Kernel;
if (!g_paniced)
queue_debug_buffer(ch);
if (g_disable_debug)
return;
if (Kernel::Serial::has_devices())
return Kernel::Serial::putchar_any(ch);
if (Kernel::TTY::is_initialized())
{
if (s_qr_code_shown)
return;
return Kernel::TTY::putchar_current(ch);
}
if (g_terminal_driver)
{

View File

@ -12,19 +12,12 @@
namespace Kernel
{
static BAN::RefPtr<FramebufferDevice> s_boot_framebuffer;
static uint32_t get_framebuffer_device_index()
{
static uint32_t index = 0;
return index++;
}
BAN::RefPtr<FramebufferDevice> FramebufferDevice::boot_framebuffer()
{
return s_boot_framebuffer;
}
BAN::ErrorOr<BAN::RefPtr<FramebufferDevice>> FramebufferDevice::create_from_boot_framebuffer()
{
ASSERT(g_boot_info.framebuffer.type == FramebufferInfo::Type::RGB);
@ -44,7 +37,6 @@ namespace Kernel
auto device = BAN::RefPtr<FramebufferDevice>::adopt(device_ptr);
TRY(device->initialize());
DevFileSystem::get().add_device(device);
s_boot_framebuffer = device;
return device;
}
@ -301,13 +293,6 @@ namespace Kernel
return BAN::UniqPtr<MemoryRegion>(BAN::move(region));
}
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> split(size_t offset) override
{
(void)offset;
dwarnln("TODO: FramebufferMemoryRegion::split");
return BAN::Error::from_errno(ENOTSUP);
}
protected:
// Returns error if no memory was available
// Returns true if page was succesfully allocated

View File

@ -2,7 +2,6 @@
#include <BAN/ScopeGuard.h>
#include <kernel/FS/Ext2/FileSystem.h>
#include <kernel/FS/Ext2/Inode.h>
#include <kernel/Lock/LockGuard.h>
#include <kernel/Timer/Timer.h>
#include <sys/stat.h>
@ -115,11 +114,8 @@ namespace Kernel
TRY(result.append(BAN::StringView(reinterpret_cast<const char*>(m_inode.block), m_inode.size)));
return result;
}
BAN::String result;
TRY(result.resize(m_inode.size));
TRY(read_impl(0, { reinterpret_cast<uint8_t*>(result.data()), result.size() }));
return BAN::move(result);
dwarnln("TODO: ext2 get symlink target from {} byte inode", m_inode.size);
return BAN::Error::from_errno(ENOTSUP);
}
BAN::ErrorOr<void> Ext2Inode::set_link_target_impl(BAN::StringView target)
@ -133,10 +129,8 @@ namespace Kernel
TRY(sync());
return {};
}
TRY(truncate_impl(target.size()));
TRY(write_impl(0, { reinterpret_cast<const uint8_t*>(target.data()), target.size() }));
return {};
dwarnln("TODO: ext2 set symlink target to {} bytes from {} byte inode", target.size(), m_inode.size);
return BAN::Error::from_errno(ENOTSUP);
}
BAN::ErrorOr<size_t> Ext2Inode::read_impl(off_t offset, BAN::ByteSpan buffer)
@ -586,37 +580,6 @@ done:
return {};
}
BAN::ErrorOr<void> Ext2Inode::rename_inode_impl(BAN::RefPtr<Inode> old_parent, BAN::StringView old_name, BAN::StringView new_name)
{
ASSERT(this->mode().ifdir());
ASSERT(old_parent->mode().ifdir());
ASSERT(&m_fs == old_parent->filesystem());
auto* ext2_parent = static_cast<Ext2Inode*>(old_parent.ptr());
// FIXME: possible deadlock :)
LockGuard _(ext2_parent->m_mutex);
auto old_inode = TRY(ext2_parent->find_inode_impl(old_name));
auto* ext2_inode = static_cast<Ext2Inode*>(old_inode.ptr());
if (auto replace_or_error = find_inode_impl(new_name); replace_or_error.is_error())
{
if (replace_or_error.error().get_error_code() != ENOENT)
return replace_or_error.release_error();
}
else
{
TRY(unlink_impl(new_name));
}
TRY(link_inode_to_directory(*ext2_inode, new_name));
TRY(ext2_parent->remove_inode_from_directory(old_name, false));
return {};
}
BAN::ErrorOr<void> Ext2Inode::link_inode_to_directory(Ext2Inode& inode, BAN::StringView name)
{
if (!this->mode().ifdir())
@ -810,7 +773,7 @@ needs_new_block:
return {};
}
BAN::ErrorOr<void> Ext2Inode::remove_inode_from_directory(BAN::StringView name, bool cleanup_directory)
BAN::ErrorOr<void> Ext2Inode::unlink_impl(BAN::StringView name)
{
ASSERT(mode().ifdir());
if (m_inode.flags & Ext2::Enum::INDEX_FL)
@ -834,7 +797,7 @@ needs_new_block:
if (entry.inode && name == BAN::StringView(entry.name, entry.name_len))
{
auto inode = TRY(Ext2Inode::create(m_fs, entry.inode));
if (cleanup_directory && inode->mode().ifdir())
if (inode->mode().ifdir())
{
if (!TRY(inode->is_directory_empty()))
return BAN::Error::from_errno(ENOTEMPTY);
@ -868,12 +831,6 @@ needs_new_block:
return {};
}
BAN::ErrorOr<void> Ext2Inode::unlink_impl(BAN::StringView name)
{
TRY(remove_inode_from_directory(name, true));
return {};
}
BAN::ErrorOr<uint32_t> Ext2Inode::allocate_new_block_to_indirect_block(uint32_t& block, uint32_t index, uint32_t depth)
{
const uint32_t inode_blocks_per_fs_block = blksize() / 512;

View File

@ -114,20 +114,6 @@ namespace Kernel
return link_inode_impl(name, inode);
}
BAN::ErrorOr<void> Inode::rename_inode(BAN::RefPtr<Inode> old_parent, BAN::StringView old_name, BAN::StringView new_name)
{
LockGuard _(m_mutex);
if (!this->mode().ifdir())
return BAN::Error::from_errno(ENOTDIR);
if (!old_parent->mode().ifdir())
return BAN::Error::from_errno(ENOTDIR);
if (this->filesystem() != old_parent->filesystem())
return BAN::Error::from_errno(EXDEV);
if (auto* fs = filesystem(); fs && (fs->flag() & ST_RDONLY))
return BAN::Error::from_errno(EROFS);
return rename_inode_impl(old_parent, old_name, new_name);
}
BAN::ErrorOr<void> Inode::unlink(BAN::StringView name)
{
LockGuard _(m_mutex);
@ -190,21 +176,21 @@ namespace Kernel
return listen_impl(backlog);
}
BAN::ErrorOr<size_t> Inode::recvmsg(msghdr& message, int flags)
BAN::ErrorOr<size_t> Inode::sendto(BAN::ConstByteSpan message, const sockaddr* address, socklen_t address_len)
{
LockGuard _(m_mutex);
if (!mode().ifsock())
return BAN::Error::from_errno(ENOTSOCK);
return recvmsg_impl(message, flags);
}
return sendto_impl(message, address, address_len);
};
BAN::ErrorOr<size_t> Inode::sendmsg(const msghdr& message, int flags)
BAN::ErrorOr<size_t> Inode::recvfrom(BAN::ByteSpan buffer, sockaddr* address, socklen_t* address_len)
{
LockGuard _(m_mutex);
if (!mode().ifsock())
return BAN::Error::from_errno(ENOTSOCK);
return sendmsg_impl(message, flags);
}
return recvfrom_impl(buffer, address, address_len);
};
BAN::ErrorOr<void> Inode::getsockname(sockaddr* address, socklen_t* address_len)
{

View File

@ -106,7 +106,7 @@ namespace Kernel
{
if (m_reading_count == 0)
{
Thread::current().add_signal(SIGPIPE, {});
Thread::current().add_signal(SIGPIPE);
return BAN::Error::from_errno(EPIPE);
}
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex));

View File

@ -43,7 +43,7 @@ namespace Kernel
[](void*) -> BAN::ErrorOr<BAN::String> {
return BAN::String::formatted("{}", Process::current().pid());
},
nullptr, nullptr, *s_instance, 0444, 0, 0)
nullptr, *s_instance, 0444, 0, 0)
);
MUST(static_cast<TmpDirectoryInode*>(s_instance->root_inode().ptr())->link_inode(*self_inode, "self"_sv));
}

View File

@ -1,7 +1,5 @@
#include <kernel/FS/ProcFS/Inode.h>
#include <ctype.h>
namespace Kernel
{
@ -17,11 +15,9 @@ namespace Kernel
TRY(inode->link_inode(*inode, "."_sv));
TRY(inode->link_inode(static_cast<TmpInode&>(*fs.root_inode()), ".."_sv));
TRY(inode->link_inode(*MUST(ProcROProcessInode::create_new(process, &Process::proc_meminfo, fs, 0400)), "meminfo"_sv));
TRY(inode->link_inode(*MUST(ProcROProcessInode::create_new(process, &Process::proc_cmdline, fs, 0444)), "cmdline"_sv));
TRY(inode->link_inode(*MUST(ProcROProcessInode::create_new(process, &Process::proc_cmdline, fs, 0400)), "cmdline"_sv));
TRY(inode->link_inode(*MUST(ProcROProcessInode::create_new(process, &Process::proc_environ, fs, 0400)), "environ"_sv));
TRY(inode->link_inode(*MUST(ProcSymlinkProcessInode::create_new(process, &Process::proc_cwd, fs, 0777)), "cwd"_sv));
TRY(inode->link_inode(*MUST(ProcSymlinkProcessInode::create_new(process, &Process::proc_exe, fs, 0777)), "exe"_sv));
TRY(inode->link_inode(*MUST(ProcFDDirectoryInode::create_new(process, fs, 0777)), "fd"_sv));
TRY(inode->link_inode(*MUST(ProcSymlinkProcessInode::create_new(process, &Process::proc_executable, fs, 0400)), "exe"_sv));
return inode;
}
@ -37,9 +33,7 @@ namespace Kernel
(void)TmpDirectoryInode::unlink_impl("meminfo"_sv);
(void)TmpDirectoryInode::unlink_impl("cmdline"_sv);
(void)TmpDirectoryInode::unlink_impl("environ"_sv);
(void)TmpDirectoryInode::unlink_impl("cwd"_sv);
(void)TmpDirectoryInode::unlink_impl("exe"_sv);
(void)TmpDirectoryInode::unlink_impl("fd"_sv);
}
BAN::ErrorOr<BAN::RefPtr<ProcROProcessInode>> ProcROProcessInode::create_new(Process& process, size_t (Process::*callback)(off_t, BAN::ByteSpan) const, TmpFileSystem& fs, mode_t mode)
@ -114,123 +108,27 @@ namespace Kernel
return m_callback(offset, buffer);
}
BAN::ErrorOr<BAN::RefPtr<ProcSymlinkInode>> ProcSymlinkInode::create_new(BAN::ErrorOr<BAN::String> (*callback)(void*), void (*destructor)(void*), void* data, TmpFileSystem& fs, mode_t mode, uid_t uid, gid_t gid)
BAN::ErrorOr<BAN::RefPtr<ProcSymlinkInode>> ProcSymlinkInode::create_new(BAN::ErrorOr<BAN::String> (*callback)(void*), void* data, TmpFileSystem& fs, mode_t mode, uid_t uid, gid_t gid)
{
auto inode_info = create_inode_info(Mode::IFLNK | mode, uid, gid);
auto* inode_ptr = new ProcSymlinkInode(callback, destructor, data, fs, inode_info);
auto* inode_ptr = new ProcSymlinkInode(callback, data, fs, inode_info);
if (inode_ptr == nullptr)
return BAN::Error::from_errno(ENOMEM);
return BAN::RefPtr<ProcSymlinkInode>::adopt(inode_ptr);
}
ProcSymlinkInode::ProcSymlinkInode(BAN::ErrorOr<BAN::String> (*callback)(void*), void (*destructor)(void*), void* data, TmpFileSystem& fs, const TmpInodeInfo& inode_info)
ProcSymlinkInode::ProcSymlinkInode(BAN::ErrorOr<BAN::String> (*callback)(void*), void* data, TmpFileSystem& fs, const TmpInodeInfo& inode_info)
: TmpInode(fs, MUST(fs.allocate_inode(inode_info)), inode_info)
, m_callback(callback)
, m_destructor(destructor)
, m_data(data)
{
m_inode_info.mode |= Inode::Mode::IFLNK;
}
ProcSymlinkInode::~ProcSymlinkInode()
{
if (m_destructor)
m_destructor(m_data);
}
BAN::ErrorOr<BAN::String> ProcSymlinkInode::link_target_impl()
{
return m_callback(m_data);
}
BAN::ErrorOr<BAN::RefPtr<ProcFDDirectoryInode>> ProcFDDirectoryInode::create_new(Process& process, TmpFileSystem& fs, mode_t mode)
{
auto inode_info = create_inode_info(Mode::IFDIR | mode, 0, 0);
auto* inode_ptr = new ProcFDDirectoryInode(process, fs, inode_info);
if (inode_ptr == nullptr)
return BAN::Error::from_errno(ENOMEM);
return BAN::RefPtr<ProcFDDirectoryInode>::adopt(inode_ptr);
}
ProcFDDirectoryInode::ProcFDDirectoryInode(Process& process, TmpFileSystem& fs, const TmpInodeInfo& inode_info)
: TmpInode(fs, MUST(fs.allocate_inode(inode_info)), inode_info)
, m_process(process)
{
ASSERT(mode().ifdir());
}
BAN::ErrorOr<BAN::RefPtr<Inode>> ProcFDDirectoryInode::find_inode_impl(BAN::StringView name)
{
int fd = 0;
for (char ch : name)
{
if (!isdigit(ch))
return BAN::Error::from_errno(ENOENT);
fd = (fd * 10) + (ch - '0');
if (fd > OPEN_MAX)
return BAN::Error::from_errno(ENOENT);
}
auto path_or_error = m_process.open_file_descriptor_set().path_of(fd);
if (path_or_error.is_error())
return BAN::Error::from_errno(ENOENT);
auto* data = new BAN::String();
if (data == nullptr)
return BAN::Error::from_errno(ENOMEM);
*data = BAN::move(path_or_error.release_value());
auto inode = TRY(ProcSymlinkInode::create_new(
[](void* data) -> BAN::ErrorOr<BAN::String>
{
BAN::String result;
TRY(result.append(*static_cast<BAN::String*>(data)));
return result;
},
[](void* data) -> void
{
delete static_cast<BAN::String*>(data);
},
data, m_fs, 0777, uid(), gid()
));
return BAN::RefPtr<Inode>(BAN::move(inode));
}
BAN::ErrorOr<size_t> ProcFDDirectoryInode::list_next_inodes_impl(off_t offset, struct dirent* list, size_t list_len)
{
if (list_len == 0)
return BAN::Error::from_errno(ENOBUFS);
auto& ofds = m_process.open_file_descriptor_set();
for (size_t fd = 0; fd < OPEN_MAX; fd++)
{
if (ofds.inode_of(fd).is_error())
continue;
if (offset-- > 0)
continue;
list[0] = {
.d_ino = 0,
.d_type = DT_LNK,
.d_name = {},
};
size_t index = 0;
BAN::Formatter::print(
[&](char ch) {
list[0].d_name[index++] = ch;
list[0].d_name[index] = '\0';
}, "{}", fd
);
return 1;
}
return 0;
}
}

View File

@ -669,44 +669,7 @@ namespace Kernel
return {};
}
BAN::ErrorOr<void> TmpDirectoryInode::rename_inode_impl(BAN::RefPtr<Inode> old_parent, BAN::StringView old_name, BAN::StringView new_name)
{
ASSERT(this->mode().ifdir());
ASSERT(old_parent->mode().ifdir());
ASSERT(&m_fs == old_parent->filesystem());
auto* tmp_parent = static_cast<TmpDirectoryInode*>(old_parent.ptr());
// FIXME: possible deadlock :)
LockGuard _(tmp_parent->m_mutex);
auto old_inode = TRY(tmp_parent->find_inode_impl(old_name));
auto* tmp_inode = static_cast<TmpInode*>(old_inode.ptr());
if (auto replace_or_error = find_inode_impl(new_name); replace_or_error.is_error())
{
if (replace_or_error.error().get_error_code() != ENOENT)
return replace_or_error.release_error();
}
else
{
TRY(unlink_impl(new_name));
}
TRY(link_inode(*tmp_inode, new_name));
TRY(tmp_parent->unlink_inode(old_name, false));
return {};
}
BAN::ErrorOr<void> TmpDirectoryInode::unlink_impl(BAN::StringView name)
{
TRY(unlink_inode(name, true));
return {};
}
BAN::ErrorOr<void> TmpDirectoryInode::unlink_inode(BAN::StringView name, bool cleanup)
{
ino_t entry_ino = 0;
@ -724,8 +687,7 @@ namespace Kernel
ASSERT(inode->nlink() > 0);
if (cleanup)
TRY(inode->prepare_unlink());
TRY(inode->prepare_unlink());
inode->m_inode_info.nlink--;
if (inode->nlink() == 0)

View File

@ -29,8 +29,7 @@ namespace Kernel
gdt->write_entry(0x20, 0x00000000, 0xFFFFF, 0xF2, data_flags); // user data
#if ARCH(i686)
gdt->write_entry(0x28, reinterpret_cast<uint32_t>(processor), sizeof(Processor), 0x92, 0x4); // processor data
gdt->write_entry(0x30, 0x00000000, 0x00000, 0xF2, data_flags); // fsbase
gdt->write_entry(0x38, 0x00000000, 0x00000, 0xF2, data_flags); // gsbase
gdt->write_entry(0x30, 0x00000000, 0x00000, 0x00, 0x0); // tls
#endif
gdt->write_tss();
@ -38,14 +37,10 @@ namespace Kernel
}
#if ARCH(i686)
void GDT::set_fsbase(uintptr_t addr)
void GDT::set_tls(uintptr_t addr)
{
write_entry(0x30, addr, 0xFFFF, 0xF2, 0xC);
}
void GDT::set_gsbase(uintptr_t addr)
{
write_entry(0x38, addr, 0xFFFF, 0xF2, 0xC);
}
#endif
void GDT::write_entry(uint8_t offset, uint32_t base, uint32_t limit, uint8_t access, uint8_t flags)

View File

@ -203,7 +203,7 @@ namespace Kernel
if (result.is_error())
{
dwarnln("Demand paging: {}", result.error());
Thread::current().handle_signal(SIGKILL, {});
Thread::current().handle_signal(SIGKILL);
goto done;
}
}
@ -236,15 +236,11 @@ namespace Kernel
"Register dump\r\n"
"rax=0x{16H}, rbx=0x{16H}, rcx=0x{16H}, rdx=0x{16H}\r\n"
"rsp=0x{16H}, rbp=0x{16H}, rdi=0x{16H}, rsi=0x{16H}\r\n"
" r8=0x{16H}, r9=0x{16H}, r10=0x{16H}, r11=0x{16H}\r\n"
"r12=0x{16H}, r13=0x{16H}, r14=0x{16H}, r15=0x{16H}\r\n"
"rip=0x{16H}, rflags=0x{16H}\r\n"
"cr0=0x{16H}, cr2=0x{16H}, cr3=0x{16H}, cr4=0x{16H}",
Processor::current_id(), isr_exceptions[isr], error, pid, tid, process_name,
regs->rax, regs->rbx, regs->rcx, regs->rdx,
interrupt_stack->sp, regs->rbp, regs->rdi, regs->rsi,
regs->r8, regs->r9, regs->r10, regs->r11,
regs->r12, regs->r13, regs->r14, regs->r15,
interrupt_stack->ip, interrupt_stack->flags,
regs->cr0, regs->cr2, regs->cr3, regs->cr4
);
@ -273,48 +269,30 @@ namespace Kernel
{
// TODO: Confirm and fix the exception to signal mappings
siginfo_t signal_info {};
int signal = 0;
switch (isr)
{
case ISR::DivisionError:
signal_info.si_signo = SIGFPE;
signal_info.si_code = FPE_INTDIV;
break;
case ISR::SIMDFloatingPointException:
case ISR::x87FloatingPointException:
// FIXME: this is probably not correct?
signal_info.si_signo = SIGFPE;
signal_info.si_code = FPE_FLTDIV;
signal = SIGFPE;
break;
case ISR::AlignmentCheck:
signal_info.si_signo = SIGBUS;
signal_info.si_code = BUS_ADRALN;
break;
case ISR::GeneralProtectionFault:
// TODO: this assumes unaligned operand but GP can be also caused by
// a privileged instruction or uncanonical address in which case
// the generated signal should be different
signal_info.si_signo = SIGBUS;
signal_info.si_code = BUS_ADRALN;
signal = SIGBUS;
break;
case ISR::InvalidOpcode:
signal_info.si_signo = SIGILL;
signal_info.si_code = ILL_ILLOPC;
signal = SIGILL;
break;
case ISR::PageFault:
signal_info.si_signo = SIGSEGV;
if (PageTable::current().get_page_flags(regs->cr2 & PAGE_ADDR_MASK) & PageTable::Flags::Present)
signal_info.si_code = SEGV_ACCERR;
else
signal_info.si_code = SEGV_MAPERR;
signal = SIGSEGV;
break;
default:
dwarnln("Unhandled exception");
signal_info.si_signo = SIGABRT;
signal = SIGABRT;
break;
}
Thread::current().handle_signal(signal_info.si_signo, signal_info);
Thread::current().handle_signal(signal);
}
else
{

View File

@ -321,7 +321,7 @@ namespace Kernel::Input
result.type = type;
BAN::Optional<ACPI::ResourceData> data;
ACPI::ResourceParser parser({ crs_obj->node.as.str_buf->bytes, static_cast<size_t>(crs_obj->node.as.str_buf->size) });
ACPI::ResourceParser parser({ crs_obj->node.as.str_buf->bytes, crs_obj->node.as.str_buf->size });
while ((data = parser.get_next()).has_value())
{
switch (data->type)

View File

@ -232,33 +232,4 @@ namespace Kernel
return BAN::UniqPtr<MemoryRegion>(BAN::move(result));
}
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> FileBackedRegion::split(size_t offset)
{
ASSERT(offset && offset < m_size);
ASSERT(offset % PAGE_SIZE == 0);
const bool has_dirty_pages = (m_type == Type::PRIVATE);
BAN::Vector<paddr_t> dirty_pages;
if (has_dirty_pages)
{
TRY(dirty_pages.resize(BAN::Math::div_round_up<size_t>(m_size - offset, PAGE_SIZE)));
for (size_t i = 0; i < dirty_pages.size(); i++)
dirty_pages[i] = m_dirty_pages[i + offset / PAGE_SIZE];
}
auto* new_region = new FileBackedRegion(m_inode, m_page_table, m_offset + offset, m_size - offset, m_type, m_flags, m_status_flags);
if (new_region == nullptr)
return BAN::Error::from_errno(ENOTSUP);
new_region->m_vaddr = m_vaddr + offset;
new_region->m_shared_data = m_shared_data;
new_region->m_dirty_pages = BAN::move(dirty_pages);
m_size = offset;
if (has_dirty_pages)
MUST(m_dirty_pages.resize(offset / PAGE_SIZE));
return BAN::UniqPtr<MemoryRegion>::adopt(new_region);
}
}

View File

@ -82,21 +82,6 @@ namespace Kernel
return BAN::UniqPtr<MemoryRegion>(BAN::move(result));
}
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> MemoryBackedRegion::split(size_t offset)
{
ASSERT(offset && offset < m_size);
ASSERT(offset % PAGE_SIZE == 0);
auto* new_region = new MemoryBackedRegion(m_page_table, m_size - offset, m_type, m_flags, m_status_flags);
if (new_region == nullptr)
return BAN::Error::from_errno(ENOMEM);
new_region->m_vaddr = m_vaddr + offset;
m_size = offset;
return BAN::UniqPtr<MemoryRegion>::adopt(new_region);
}
BAN::ErrorOr<void> MemoryBackedRegion::copy_data_to_region(size_t offset_into_region, const uint8_t* buffer, size_t buffer_size)
{
ASSERT(offset_into_region + buffer_size <= m_size);

View File

@ -50,11 +50,6 @@ namespace Kernel
return true;
}
bool MemoryRegion::is_contained_by(vaddr_t address, size_t size) const
{
return address <= m_vaddr && m_vaddr + m_size <= address + size;
}
BAN::ErrorOr<void> MemoryRegion::mprotect(PageTable::flags_t new_page_flags)
{
if (m_flags == new_page_flags)

View File

@ -87,13 +87,6 @@ namespace Kernel
return BAN::UniqPtr<MemoryRegion>(BAN::move(region));
}
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> SharedMemoryObject::split(size_t offset)
{
(void)offset;
dwarnln("TODO: SharedMemoryObject::split");
return BAN::Error::from_errno(ENOTSUP);
}
BAN::ErrorOr<bool> SharedMemoryObject::allocate_page_containing_impl(vaddr_t address, bool wants_write)
{
ASSERT(contains(address));

View File

@ -1,4 +1,5 @@
#include <BAN/Errors.h>
#include <kernel/kprint.h>
#include <kernel/BootInfo.h>
#include <kernel/Memory/kmalloc.h>
@ -152,13 +153,13 @@ void kmalloc_dump_info()
{
Kernel::SpinLockGuard _(s_kmalloc_lock);
dprintln("kmalloc: 0x{8H}->0x{8H}", s_kmalloc_info.base, s_kmalloc_info.end);
dprintln(" used: 0x{8H}", s_kmalloc_info.used);
dprintln(" free: 0x{8H}", s_kmalloc_info.free);
kprintln("kmalloc: 0x{8H}->0x{8H}", s_kmalloc_info.base, s_kmalloc_info.end);
kprintln(" used: 0x{8H}", s_kmalloc_info.used);
kprintln(" free: 0x{8H}", s_kmalloc_info.free);
dprintln("kmalloc fixed {} byte: 0x{8H}->0x{8H}", sizeof(kmalloc_fixed_info::node), s_kmalloc_fixed_info.base, s_kmalloc_fixed_info.end);
dprintln(" used: 0x{8H}", s_kmalloc_fixed_info.used);
dprintln(" free: 0x{8H}", s_kmalloc_fixed_info.free);
kprintln("kmalloc fixed {} byte: 0x{8H}->0x{8H}", sizeof(kmalloc_fixed_info::node), s_kmalloc_fixed_info.base, s_kmalloc_fixed_info.end);
kprintln(" used: 0x{8H}", s_kmalloc_fixed_info.used);
kprintln(" free: 0x{8H}", s_kmalloc_fixed_info.free);
}
static bool is_corrupted()

View File

@ -36,7 +36,7 @@ namespace Kernel
ARPTable::~ARPTable()
{
if (m_thread)
m_thread->add_signal(SIGKILL, {});
m_thread->add_signal(SIGKILL);
m_thread = nullptr;
}

View File

@ -47,7 +47,7 @@ namespace Kernel
IPv4Layer::~IPv4Layer()
{
if (m_thread)
m_thread->add_signal(SIGKILL, {});
m_thread->add_signal(SIGKILL);
m_thread = nullptr;
}

View File

@ -190,21 +190,8 @@ namespace Kernel
return m_network_layer.bind_socket_to_address(this, address, address_len);
}
BAN::ErrorOr<size_t> TCPSocket::recvmsg_impl(msghdr& message, int flags)
BAN::ErrorOr<size_t> TCPSocket::recvfrom_impl(BAN::ByteSpan buffer, sockaddr*, socklen_t*)
{
flags &= (MSG_OOB | MSG_PEEK | MSG_WAITALL);
if (flags != 0)
{
dwarnln("TODO: recvmsg with flags 0x{H}", flags);
return BAN::Error::from_errno(ENOTSUP);
}
if (CMSG_FIRSTHDR(&message))
{
dwarnln("ignoring recvmsg control message");
message.msg_controllen = 0;
}
if (!m_has_connected)
return BAN::Error::from_errno(ENOTCONN);
@ -215,43 +202,26 @@ namespace Kernel
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex));
}
message.msg_flags = 0;
const uint32_t to_recv = BAN::Math::min<uint32_t>(buffer.size(), m_recv_window.data_size);
size_t total_recv = 0;
for (int i = 0; i < message.msg_iovlen; i++)
{
auto* recv_buffer = reinterpret_cast<uint8_t*>(m_recv_window.buffer->vaddr());
auto* recv_buffer = reinterpret_cast<uint8_t*>(m_recv_window.buffer->vaddr());
memcpy(buffer.data(), recv_buffer, to_recv);
const size_t nrecv = BAN::Math::min<size_t>(message.msg_iov[i].iov_len, m_recv_window.data_size);
memcpy(message.msg_iov[i].iov_base, recv_buffer, nrecv);
m_recv_window.data_size -= to_recv;
m_recv_window.start_seq += to_recv;
if (m_recv_window.data_size > 0)
memmove(recv_buffer, recv_buffer + to_recv, m_recv_window.data_size);
total_recv += nrecv;
m_recv_window.data_size -= nrecv;
m_recv_window.start_seq += nrecv;
if (m_recv_window.data_size == 0)
break;
// TODO: use circular buffer to avoid this
memmove(recv_buffer, recv_buffer + nrecv, m_recv_window.data_size);
}
return total_recv;
return to_recv;
}
BAN::ErrorOr<size_t> TCPSocket::sendmsg_impl(const msghdr& message, int flags)
BAN::ErrorOr<size_t> TCPSocket::sendto_impl(BAN::ConstByteSpan message, const sockaddr* address, socklen_t address_len)
{
if (flags & MSG_NOSIGNAL)
dwarnln("sendmsg ignoring MSG_NOSIGNAL");
flags &= (MSG_EOR | MSG_OOB /* | MSG_NOSIGNAL */);
if (flags != 0)
{
dwarnln("TODO: sendmsg with flags 0x{H}", flags);
return BAN::Error::from_errno(ENOTSUP);
}
if (CMSG_FIRSTHDR(&message))
dwarnln("ignoring sendmsg control message");
(void)address;
(void)address_len;
if (address)
return BAN::Error::from_errno(EISCONN);
if (!m_has_connected)
return BAN::Error::from_errno(ENOTCONN);
@ -262,23 +232,17 @@ namespace Kernel
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex));
}
size_t total_sent = 0;
for (int i = 0; i < message.msg_iovlen; i++)
const size_t to_send = BAN::Math::min<size_t>(message.size(), m_send_window.buffer->size() - m_send_window.data_size);
{
auto* send_buffer = reinterpret_cast<uint8_t*>(m_send_window.buffer->vaddr());
const size_t nsend = BAN::Math::min<size_t>(message.msg_iov[i].iov_len, m_send_window.buffer->size() - m_send_window.data_size);
memcpy(send_buffer + m_send_window.data_size, message.msg_iov[i].iov_base, nsend);
total_sent += nsend;
m_send_window.data_size += nsend;
if (m_send_window.data_size == m_send_window.buffer->size())
break;
auto* buffer = reinterpret_cast<uint8_t*>(m_send_window.buffer->vaddr());
memcpy(buffer + m_send_window.data_size, message.data(), to_send);
m_send_window.data_size += to_send;
}
m_thread_blocker.unblock();
return total_sent;
return to_send;
}
BAN::ErrorOr<void> TCPSocket::getpeername_impl(sockaddr* address, socklen_t* address_len)

View File

@ -79,15 +79,6 @@ namespace Kernel
m_packet_thread_blocker.unblock();
}
BAN::ErrorOr<void> UDPSocket::connect_impl(const sockaddr* address, socklen_t address_len)
{
if (address_len > static_cast<socklen_t>(sizeof(m_peer_address)))
address_len = sizeof(m_peer_address);
memcpy(&m_peer_address, address, address_len);
m_peer_address_len = address_len;
return {};
}
BAN::ErrorOr<void> UDPSocket::bind_impl(const sockaddr* address, socklen_t address_len)
{
if (is_bound())
@ -95,21 +86,8 @@ namespace Kernel
return m_network_layer.bind_socket_to_address(this, address, address_len);
}
BAN::ErrorOr<size_t> UDPSocket::recvmsg_impl(msghdr& message, int flags)
BAN::ErrorOr<size_t> UDPSocket::recvfrom_impl(BAN::ByteSpan buffer, sockaddr* address, socklen_t* address_len)
{
flags &= (MSG_OOB | MSG_PEEK | MSG_WAITALL);
if (flags != 0)
{
dwarnln("TODO: recvmsg with flags 0x{H}", flags);
return BAN::Error::from_errno(ENOTSUP);
}
if (CMSG_FIRSTHDR(&message))
{
dwarnln("ignoring recvmsg control message");
message.msg_controllen = 0;
}
if (!is_bound())
{
dprintln("No interface bound");
@ -128,21 +106,14 @@ namespace Kernel
auto packet_info = m_packets.front();
m_packets.pop();
auto* packet_buffer = reinterpret_cast<uint8_t*>(m_packet_buffer->vaddr());
message.msg_flags = 0;
size_t total_recv = 0;
for (int i = 0; i < message.msg_iovlen; i++)
{
const size_t nrecv = BAN::Math::min<size_t>(message.msg_iov[i].iov_len, packet_info.packet_size - total_recv);
memcpy(message.msg_iov[i].iov_base, packet_buffer + total_recv, nrecv);
total_recv += nrecv;
if (nrecv < packet_info.packet_size)
message.msg_flags |= MSG_TRUNC;
}
size_t nread = BAN::Math::min<size_t>(packet_info.packet_size, buffer.size());
uint8_t* packet_buffer = reinterpret_cast<uint8_t*>(m_packet_buffer->vaddr());
memcpy(
buffer.data(),
packet_buffer,
nread
);
memmove(
packet_buffer,
packet_buffer + packet_info.packet_size,
@ -151,67 +122,21 @@ namespace Kernel
m_packet_total_size -= packet_info.packet_size;
if (message.msg_name && message.msg_namelen)
if (address && address_len)
{
const size_t namelen = BAN::Math::min<size_t>(message.msg_namelen, sizeof(sockaddr_storage));
memcpy(message.msg_name, &packet_info.sender, namelen);
message.msg_namelen = namelen;
if (*address_len > (socklen_t)sizeof(sockaddr_storage))
*address_len = sizeof(sockaddr_storage);
memcpy(address, &packet_info.sender, *address_len);
}
return total_recv;
return nread;
}
BAN::ErrorOr<size_t> UDPSocket::sendmsg_impl(const msghdr& message, int flags)
BAN::ErrorOr<size_t> UDPSocket::sendto_impl(BAN::ConstByteSpan message, const sockaddr* address, socklen_t address_len)
{
if (flags & MSG_NOSIGNAL)
dwarnln("sendmsg ignoring MSG_NOSIGNAL");
flags &= (MSG_EOR | MSG_OOB /* | MSG_NOSIGNAL */);
if (flags != 0)
{
dwarnln("TODO: sendmsg with flags 0x{H}", flags);
return BAN::Error::from_errno(ENOTSUP);
}
if (CMSG_FIRSTHDR(&message))
dwarnln("ignoring sendmsg control message");
if (!is_bound())
TRY(m_network_layer.bind_socket_to_unused(this, static_cast<sockaddr*>(message.msg_name), message.msg_namelen));
const size_t total_send_size =
[&message]() -> size_t {
size_t result = 0;
for (int i = 0; i < message.msg_iovlen; i++)
result += message.msg_iov[i].iov_len;
return result;
}();
BAN::Vector<uint8_t> buffer;
TRY(buffer.resize(total_send_size));
size_t offset = 0;
for (int i = 0; i < message.msg_iovlen; i++)
{
memcpy(buffer.data() + offset, message.msg_iov[i].iov_base, message.msg_iov[i].iov_len);
offset += message.msg_iov[i].iov_len;
}
sockaddr* address;
socklen_t address_len;
if (!message.msg_name || message.msg_namelen == 0)
{
if (m_peer_address_len == 0)
return BAN::Error::from_errno(EDESTADDRREQ);
address = reinterpret_cast<sockaddr*>(&m_peer_address);
address_len = m_peer_address_len;
}
else
{
address = static_cast<sockaddr*>(message.msg_name);
address_len = message.msg_namelen;
}
return TRY(m_network_layer.sendto(*this, buffer.span(), address, address_len));
TRY(m_network_layer.bind_socket_to_unused(this, address, address_len));
return TRY(m_network_layer.sendto(*this, message, address, address_len));
}
BAN::ErrorOr<long> UDPSocket::ioctl_impl(int request, void* argument)

View File

@ -1,7 +1,6 @@
#include <BAN/HashMap.h>
#include <kernel/FS/VirtualFileSystem.h>
#include <kernel/Lock/LockGuard.h>
#include <kernel/Lock/SpinLockAsMutex.h>
#include <kernel/Networking/NetworkManager.h>
#include <kernel/Networking/UNIX/Socket.h>
#include <kernel/Process.h>
@ -23,28 +22,10 @@ namespace Kernel
};
static BAN::HashMap<BAN::RefPtr<Inode>, BAN::WeakPtr<UnixDomainSocket>, UnixSocketHash> s_bound_sockets;
static Mutex s_bound_socket_lock;
static SpinLock s_bound_socket_lock;
static constexpr size_t s_packet_buffer_size = 10 * PAGE_SIZE;
static BAN::ErrorOr<BAN::StringView> validate_sockaddr_un(const sockaddr* address, socklen_t address_len)
{
if (address_len < static_cast<socklen_t>(sizeof(sa_family_t)))
return BAN::Error::from_errno(EINVAL);
if (address_len > static_cast<socklen_t>(sizeof(sockaddr_un)))
address_len = sizeof(sockaddr_un);
const auto& sockaddr_un = *reinterpret_cast<const struct sockaddr_un*>(address);
if (sockaddr_un.sun_family != AF_UNIX)
return BAN::Error::from_errno(EINVAL);
size_t length = 0;
while (length < address_len - sizeof(sa_family_t) && sockaddr_un.sun_path[length])
length++;
return BAN::StringView { sockaddr_un.sun_path, length };
}
// FIXME: why is this using spinlocks instead of mutexes??
BAN::ErrorOr<BAN::RefPtr<UnixDomainSocket>> UnixDomainSocket::create(Socket::Type socket_type, const Socket::Info& info)
@ -83,7 +64,7 @@ namespace Kernel
{
if (is_bound() && !is_bound_to_unused())
{
LockGuard _(s_bound_socket_lock);
SpinLockGuard _(s_bound_socket_lock);
s_bound_sockets.remove(m_bound_file.inode);
}
if (m_info.has<ConnectionInfo>())
@ -124,9 +105,11 @@ namespace Kernel
BAN::RefPtr<UnixDomainSocket> pending;
{
LockGuard _(connection_info.pending_lock);
SpinLockGuard guard(connection_info.pending_lock);
SpinLockGuardAsMutex smutex(guard);
while (connection_info.pending_connections.empty())
TRY(Thread::current().block_or_eintr_indefinite(connection_info.pending_thread_blocker, &connection_info.pending_lock));
TRY(Thread::current().block_or_eintr_indefinite(connection_info.pending_thread_blocker, &smutex));
pending = connection_info.pending_connections.front();
connection_info.pending_connections.pop();
@ -163,11 +146,15 @@ namespace Kernel
BAN::ErrorOr<void> UnixDomainSocket::connect_impl(const sockaddr* address, socklen_t address_len)
{
const auto sun_path = TRY(validate_sockaddr_un(address, address_len));
if (address_len != sizeof(sockaddr_un))
return BAN::Error::from_errno(EINVAL);
auto& sockaddr_un = *reinterpret_cast<const struct sockaddr_un*>(address);
if (sockaddr_un.sun_family != AF_UNIX)
return BAN::Error::from_errno(EAFNOSUPPORT);
if (!is_bound())
TRY(m_bound_file.canonical_path.push_back('X'));
auto absolute_path = TRY(Process::current().absolute_path_of(sun_path));
auto absolute_path = TRY(Process::current().absolute_path_of(sockaddr_un.sun_path));
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(
Process::current().root_file().inode,
Process::current().credentials(),
@ -178,7 +165,7 @@ namespace Kernel
BAN::RefPtr<UnixDomainSocket> target;
{
LockGuard _(s_bound_socket_lock);
SpinLockGuard _(s_bound_socket_lock);
auto it = s_bound_sockets.find(file.inode);
if (it == s_bound_sockets.end())
return BAN::Error::from_errno(ECONNREFUSED);
@ -209,7 +196,7 @@ namespace Kernel
{
auto& target_info = target->m_info.get<ConnectionInfo>();
LockGuard _(target_info.pending_lock);
SpinLockGuard guard(target_info.pending_lock);
if (target_info.pending_connections.size() < target_info.pending_connections.capacity())
{
@ -218,7 +205,8 @@ namespace Kernel
break;
}
TRY(Thread::current().block_or_eintr_indefinite(target_info.pending_thread_blocker, &target_info.pending_lock));
SpinLockGuardAsMutex smutex(guard);
TRY(Thread::current().block_or_eintr_indefinite(target_info.pending_thread_blocker, &smutex));
}
target->epoll_notify(EPOLLIN);
@ -248,16 +236,21 @@ namespace Kernel
{
if (is_bound())
return BAN::Error::from_errno(EINVAL);
if (address_len != sizeof(sockaddr_un))
return BAN::Error::from_errno(EINVAL);
auto& sockaddr_un = *reinterpret_cast<const struct sockaddr_un*>(address);
if (sockaddr_un.sun_family != AF_UNIX)
return BAN::Error::from_errno(EAFNOSUPPORT);
const auto sun_path = TRY(validate_sockaddr_un(address, address_len));
if (sun_path.empty())
auto bind_path = BAN::StringView(sockaddr_un.sun_path);
if (bind_path.empty())
return BAN::Error::from_errno(EINVAL);
// FIXME: This feels sketchy
auto parent_file = sun_path.front() == '/'
auto parent_file = bind_path.front() == '/'
? TRY(Process::current().root_file().clone())
: TRY(Process::current().working_directory().clone());
if (auto ret = Process::current().create_file_or_dir(AT_FDCWD, sun_path.data(), 0755 | S_IFSOCK); ret.is_error())
if (auto ret = Process::current().create_file_or_dir(AT_FDCWD, bind_path.data(), 0755 | S_IFSOCK); ret.is_error())
{
if (ret.error().get_error_code() == EEXIST)
return BAN::Error::from_errno(EADDRINUSE);
@ -267,11 +260,11 @@ namespace Kernel
Process::current().root_file().inode,
parent_file,
Process::current().credentials(),
sun_path,
bind_path,
O_RDWR
));
LockGuard _(s_bound_socket_lock);
SpinLockGuard _(s_bound_socket_lock);
if (s_bound_sockets.contains(file.inode))
return BAN::Error::from_errno(EADDRINUSE);
TRY(s_bound_sockets.emplace(file.inode, TRY(get_weak_ptr())));
@ -294,25 +287,21 @@ namespace Kernel
}
}
BAN::ErrorOr<void> UnixDomainSocket::add_packet(const msghdr& packet, PacketInfo&& packet_info)
BAN::ErrorOr<void> UnixDomainSocket::add_packet(BAN::ConstByteSpan packet)
{
LockGuard _(m_packet_lock);
while (m_packet_infos.full() || m_packet_size_total + packet_info.size > s_packet_buffer_size)
TRY(Thread::current().block_or_eintr_indefinite(m_packet_thread_blocker, &m_packet_lock));
uint8_t* packet_buffer = reinterpret_cast<uint8_t*>(m_packet_buffer->vaddr() + m_packet_size_total);
size_t offset = 0;
for (int i = 0; i < packet.msg_iovlen; i++)
SpinLockGuard guard(m_packet_lock);
while (m_packet_sizes.full() || m_packet_size_total + packet.size() > s_packet_buffer_size)
{
memcpy(packet_buffer + offset, packet.msg_iov[i].iov_base, packet.msg_iov[i].iov_len);
offset += packet.msg_iov[i].iov_len;
SpinLockGuardAsMutex smutex(guard);
TRY(Thread::current().block_or_eintr_indefinite(m_packet_thread_blocker, &smutex));
}
ASSERT(offset == packet_info.size);
m_packet_size_total += packet_info.size;
m_packet_infos.emplace(BAN::move(packet_info));
uint8_t* packet_buffer = reinterpret_cast<uint8_t*>(m_packet_buffer->vaddr() + m_packet_size_total);
memcpy(packet_buffer, packet.data(), packet.size());
m_packet_size_total += packet.size();
if (!is_streaming())
m_packet_sizes.push(packet.size());
m_packet_thread_blocker.unblock();
@ -326,10 +315,10 @@ namespace Kernel
if (m_info.has<ConnectionInfo>())
{
auto& connection_info = m_info.get<ConnectionInfo>();
if (connection_info.listening)
return !connection_info.pending_connections.empty();
if (connection_info.target_closed)
return true;
if (!connection_info.pending_connections.empty())
return true;
if (!connection_info.connection)
return false;
}
@ -342,13 +331,7 @@ namespace Kernel
if (m_info.has<ConnectionInfo>())
{
auto& connection_info = m_info.get<ConnectionInfo>();
auto connection = connection_info.connection.lock();
if (!connection)
return false;
if (connection->m_packet_infos.full())
return false;
if (connection->m_packet_size_total >= s_packet_buffer_size)
return false;
return connection_info.connection.valid();
}
return true;
@ -365,257 +348,27 @@ namespace Kernel
return false;
}
BAN::ErrorOr<size_t> UnixDomainSocket::recvmsg_impl(msghdr& message, int flags)
BAN::ErrorOr<size_t> UnixDomainSocket::sendto_impl(BAN::ConstByteSpan message, const sockaddr* address, socklen_t address_len)
{
flags &= (MSG_OOB | MSG_PEEK | MSG_WAITALL);
if (flags != 0)
{
dwarnln("TODO: recvmsg with flags 0x{H}", flags);
return BAN::Error::from_errno(ENOTSUP);
}
LockGuard _(m_packet_lock);
while (m_packet_size_total == 0)
{
if (m_info.has<ConnectionInfo>())
{
auto& connection_info = m_info.get<ConnectionInfo>();
bool expected = true;
if (connection_info.target_closed.compare_exchange(expected, false))
return 0;
if (!connection_info.connection)
return BAN::Error::from_errno(ENOTCONN);
}
TRY(Thread::current().block_or_eintr_indefinite(m_packet_thread_blocker, &m_packet_lock));
}
auto* cheader = CMSG_FIRSTHDR(&message);
if (cheader != nullptr)
cheader->cmsg_len = message.msg_controllen;
size_t cheader_len = 0;
uint8_t* packet_buffer = reinterpret_cast<uint8_t*>(m_packet_buffer->vaddr());
message.msg_flags = 0;
int iov_index = 0;
size_t iov_offset = 0;
size_t total_recv = 0;
while (!m_packet_infos.empty() && iov_index < message.msg_iovlen)
{
auto& packet_info = m_packet_infos.front();
auto fds_to_open = BAN::move(packet_info.fds);
auto ucred_to_recv = BAN::move(packet_info.ucred);
const bool had_ancillary_data = !fds_to_open.empty() || ucred_to_recv.has_value();
if (!fds_to_open.empty()) do
{
if (cheader == nullptr)
{
dwarnln("no space to receive {} fds", fds_to_open.size());
message.msg_flags |= MSG_CTRUNC;
break;
}
const size_t max_fd_count = (cheader->cmsg_len - sizeof(cmsghdr)) / sizeof(int);
if (max_fd_count < fds_to_open.size())
message.msg_flags |= MSG_CTRUNC;
const size_t fd_count = BAN::Math::min(fds_to_open.size(), max_fd_count);
const size_t fds_opened = Process::current().open_file_descriptor_set().open_all_fd_wrappers(fds_to_open.span().slice(0, fd_count));
auto* fd_data = reinterpret_cast<int*>(CMSG_DATA(cheader));
for (size_t i = 0; i < fds_opened; i++)
fd_data[i] = fds_to_open[i].fd();
const size_t header_length = CMSG_LEN(fds_opened * sizeof(int));
cheader->cmsg_level = SOL_SOCKET;
cheader->cmsg_type = SCM_RIGHTS;
cheader->cmsg_len = header_length;
cheader = CMSG_NXTHDR(&message, cheader);
if (cheader != nullptr)
cheader->cmsg_len = message.msg_controllen - header_length;
cheader_len += header_length;
} while (false);
if (ucred_to_recv.has_value()) do
{
if (cheader == nullptr || cheader->cmsg_len - sizeof(cmsghdr) < sizeof(struct ucred))
{
dwarnln("no space to receive credentials");
message.msg_flags |= MSG_CTRUNC;
break;
}
*reinterpret_cast<struct ucred*>(CMSG_DATA(cheader)) = ucred_to_recv.value();
const size_t header_length = CMSG_LEN(sizeof(struct ucred));
cheader->cmsg_level = SOL_SOCKET;
cheader->cmsg_type = SCM_CREDENTIALS;
cheader->cmsg_len = header_length;
cheader = CMSG_NXTHDR(&message, cheader);
if (cheader != nullptr)
cheader->cmsg_len = message.msg_controllen - header_length;
cheader_len += header_length;
} while (false);
size_t packet_received = 0;
while (iov_index < message.msg_iovlen && packet_received < packet_info.size)
{
auto& iov = message.msg_iov[iov_index];
uint8_t* iov_base = static_cast<uint8_t*>(iov.iov_base);
const size_t nrecv = BAN::Math::min<size_t>(iov.iov_len - iov_offset, packet_info.size - packet_received);
memcpy(iov_base + iov_offset, packet_buffer + packet_received, nrecv);
packet_received += nrecv;
iov_offset += nrecv;
if (iov_offset >= iov.iov_len)
{
iov_offset = 0;
iov_index++;
}
}
if (!is_streaming() && packet_received < packet_info.size)
message.msg_flags |= MSG_TRUNC;
const size_t to_discard = is_streaming() ? packet_received : packet_info.size;
packet_info.size -= to_discard;
if (packet_info.size == 0)
m_packet_infos.pop();
// FIXME: get rid of this memmove :)
memmove(packet_buffer, packet_buffer + to_discard, m_packet_size_total - to_discard);
m_packet_size_total -= to_discard;
total_recv += packet_received;
// on linux ancillary data is a barrier on stream sockets, lets do the same
if (!is_streaming() || had_ancillary_data)
break;
}
message.msg_controllen = cheader_len;
m_packet_thread_blocker.unblock();
epoll_notify(EPOLLOUT);
return total_recv;
}
BAN::ErrorOr<size_t> UnixDomainSocket::sendmsg_impl(const msghdr& message, int flags)
{
if (flags & MSG_NOSIGNAL)
dwarnln("sendmsg ignoring MSG_NOSIGNAL");
flags &= (MSG_EOR | MSG_OOB /* | MSG_NOSIGNAL */);
if (flags != 0)
{
dwarnln("TODO: sendmsg with flags 0x{H}", flags);
return BAN::Error::from_errno(ENOTSUP);
}
const size_t total_message_size =
[&message]() -> size_t {
size_t result = 0;
for (int i = 0; i < message.msg_iovlen; i++)
result += message.msg_iov[i].iov_len;
return result;
}();
if (total_message_size > s_packet_buffer_size)
if (message.size() > s_packet_buffer_size)
return BAN::Error::from_errno(ENOBUFS);
PacketInfo packet_info {
.size = total_message_size,
.fds = {},
.ucred = {},
};
for (const auto* header = CMSG_FIRSTHDR(&message); header; header = CMSG_NXTHDR(&message, header))
{
if (header->cmsg_level != SOL_SOCKET)
{
dwarnln("ignoring control message with level {}", header->cmsg_level);
continue;
}
switch (header->cmsg_type)
{
case SCM_RIGHTS:
{
if (!packet_info.fds.empty())
{
dwarnln("multiple SCM_RIGHTS in one sendmsg");
return BAN::Error::from_errno(EINVAL);
}
const auto* fd_data = reinterpret_cast<const int*>(CMSG_DATA(header));
const size_t fd_count = (header->cmsg_len - sizeof(cmsghdr)) / sizeof(int);
for (size_t i = 0; i < fd_count; i++)
TRY(packet_info.fds.push_back(TRY(Process::current().open_file_descriptor_set().get_fd_wrapper(fd_data[i]))));
break;
}
case SCM_CREDENTIALS:
{
if (packet_info.ucred.has_value())
{
dwarnln("multiple SCM_CREDENTIALS in one sendmsg");
return BAN::Error::from_errno(EINVAL);
}
if (header->cmsg_len - sizeof(cmsghdr) < sizeof(struct ucred))
return BAN::Error::from_errno(EINVAL);
const ucred* ucred = reinterpret_cast<const struct ucred*>(CMSG_DATA(header));
const bool is_valid_ucred =
[ucred]() -> bool
{
const auto& creds = Process::current().credentials();
if (creds.is_superuser())
return true;
if (ucred->pid != Process::current().pid())
return false;
if (ucred->uid != creds.ruid() && ucred->uid != creds.euid() && ucred->uid != creds.suid())
return false;
if (ucred->gid != creds.rgid() && !creds.has_egid(ucred->gid) && ucred->gid != creds.sgid())
return false;
return true;
}();
if (!is_valid_ucred)
return BAN::Error::from_errno(EPERM);
packet_info.ucred = *ucred;
break;
}
default:
dwarnln("ignoring control message with type {}", header->cmsg_type);
break;
}
}
if (m_info.has<ConnectionInfo>())
{
auto& connection_info = m_info.get<ConnectionInfo>();
if (address)
return BAN::Error::from_errno(EISCONN);
auto target = connection_info.connection.lock();
if (!target)
return BAN::Error::from_errno(ENOTCONN);
TRY(target->add_packet(message, BAN::move(packet_info)));
return total_message_size;
TRY(target->add_packet(message));
return message.size();
}
else
{
BAN::RefPtr<Inode> target_inode;
if (!message.msg_name || message.msg_namelen == 0)
if (!address)
{
auto& connectionless_info = m_info.get<ConnectionlessInfo>();
if (connectionless_info.peer_address.empty())
@ -631,8 +384,13 @@ namespace Kernel
}
else
{
const auto sun_path = TRY(validate_sockaddr_un(static_cast<sockaddr*>(message.msg_name), message.msg_namelen));
auto absolute_path = TRY(Process::current().absolute_path_of(sun_path));
if (address_len != sizeof(sockaddr_un))
return BAN::Error::from_errno(EINVAL);
auto& sockaddr_un = *reinterpret_cast<const struct sockaddr_un*>(address);
if (sockaddr_un.sun_family != AF_UNIX)
return BAN::Error::from_errno(EAFNOSUPPORT);
auto absolute_path = TRY(Process::current().absolute_path_of(sockaddr_un.sun_path));
target_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(
Process::current().root_file().inode,
Process::current().credentials(),
@ -641,23 +399,59 @@ namespace Kernel
)).inode;
}
BAN::RefPtr<UnixDomainSocket> target;
{
LockGuard _(s_bound_socket_lock);
auto it = s_bound_sockets.find(target_inode);
if (it == s_bound_sockets.end())
return BAN::Error::from_errno(EDESTADDRREQ);
target = it->value.lock();
}
SpinLockGuard _(s_bound_socket_lock);
auto it = s_bound_sockets.find(target_inode);
if (it == s_bound_sockets.end())
return BAN::Error::from_errno(EDESTADDRREQ);
auto target = it->value.lock();
if (!target)
return BAN::Error::from_errno(EDESTADDRREQ);
TRY(target->add_packet(message, BAN::move(packet_info)));
return total_message_size;
TRY(target->add_packet(message));
return message.size();
}
}
BAN::ErrorOr<size_t> UnixDomainSocket::recvfrom_impl(BAN::ByteSpan buffer, sockaddr*, socklen_t*)
{
SpinLockGuard guard(m_packet_lock);
while (m_packet_size_total == 0)
{
if (m_info.has<ConnectionInfo>())
{
auto& connection_info = m_info.get<ConnectionInfo>();
bool expected = true;
if (connection_info.target_closed.compare_exchange(expected, false))
return 0;
if (!connection_info.connection)
return BAN::Error::from_errno(ENOTCONN);
}
SpinLockGuardAsMutex smutex(guard);
TRY(Thread::current().block_or_eintr_indefinite(m_packet_thread_blocker, &smutex));
}
uint8_t* packet_buffer = reinterpret_cast<uint8_t*>(m_packet_buffer->vaddr());
size_t nread = 0;
if (is_streaming())
nread = BAN::Math::min(buffer.size(), m_packet_size_total);
else
{
nread = BAN::Math::min(buffer.size(), m_packet_sizes.front());
m_packet_sizes.pop();
}
memcpy(buffer.data(), packet_buffer, nread);
memmove(packet_buffer, packet_buffer + nread, m_packet_size_total - nread);
m_packet_size_total -= nread;
m_packet_thread_blocker.unblock();
epoll_notify(EPOLLOUT);
return nread;
}
BAN::ErrorOr<void> UnixDomainSocket::getpeername_impl(sockaddr* address, socklen_t* address_len)
{
if (!m_info.has<ConnectionInfo>())

View File

@ -217,7 +217,7 @@ namespace Kernel
return fildes;
}
BAN::ErrorOr<int> OpenFileDescriptorSet::fcntl(int fd, int cmd, uintptr_t extra)
BAN::ErrorOr<int> OpenFileDescriptorSet::fcntl(int fd, int cmd, int extra)
{
LockGuard _(m_mutex);
@ -424,24 +424,7 @@ namespace Kernel
}
if (inode->mode().ifsock())
{
iovec iov {
.iov_base = buffer.data(),
.iov_len = buffer.size(),
};
msghdr message {
.msg_name = nullptr,
.msg_namelen = 0,
.msg_iov = &iov,
.msg_iovlen = 1,
.msg_control = nullptr,
.msg_controllen = 0,
.msg_flags = 0,
};
return recvmsg(fd, message, 0);
}
return recvfrom(fd, buffer, nullptr, nullptr);
size_t nread;
{
@ -478,31 +461,14 @@ namespace Kernel
}
if (inode->mode().ifsock())
{
iovec iov {
.iov_base = const_cast<uint8_t*>(buffer.data()),
.iov_len = buffer.size(),
};
msghdr message {
.msg_name = nullptr,
.msg_namelen = 0,
.msg_iov = &iov,
.msg_iovlen = 1,
.msg_control = nullptr,
.msg_controllen = 0,
.msg_flags = 0,
};
return sendmsg(fd, message, 0);
}
return sendto(fd, buffer, nullptr, 0);
size_t nwrite;
{
LockGuard _(inode->m_mutex);
if (inode->has_error())
{
Thread::current().add_signal(SIGPIPE, {});
Thread::current().add_signal(SIGPIPE);
return BAN::Error::from_errno(EPIPE);
}
if (is_nonblock && !inode->can_write())
@ -549,7 +515,7 @@ namespace Kernel
}
}
BAN::ErrorOr<size_t> OpenFileDescriptorSet::recvmsg(int fd, msghdr& message, int flags)
BAN::ErrorOr<size_t> OpenFileDescriptorSet::recvfrom(int fd, BAN::ByteSpan buffer, sockaddr* address, socklen_t* address_len)
{
BAN::RefPtr<Inode> inode;
bool is_nonblock;
@ -567,10 +533,10 @@ namespace Kernel
LockGuard _(inode->m_mutex);
if (is_nonblock && !inode->can_read())
return BAN::Error::from_errno(EWOULDBLOCK);
return inode->recvmsg(message, flags);
return inode->recvfrom(buffer, address, address_len);
}
BAN::ErrorOr<size_t> OpenFileDescriptorSet::sendmsg(int fd, const msghdr& message, int flags)
BAN::ErrorOr<size_t> OpenFileDescriptorSet::sendto(int fd, BAN::ConstByteSpan buffer, const sockaddr* address, socklen_t address_len)
{
BAN::RefPtr<Inode> inode;
bool is_nonblock;
@ -588,12 +554,12 @@ namespace Kernel
LockGuard _(inode->m_mutex);
if (inode->has_hungup())
{
Thread::current().add_signal(SIGPIPE, {});
Thread::current().add_signal(SIGPIPE);
return BAN::Error::from_errno(EPIPE);
}
if (is_nonblock && !inode->can_write())
return BAN::Error::from_errno(EWOULDBLOCK);
return inode->sendmsg(message, flags);
return inode->sendto(buffer, address, address_len);
}
BAN::ErrorOr<VirtualFileSystem::File> OpenFileDescriptorSet::file_of(int fd) const
@ -659,66 +625,4 @@ namespace Kernel
return BAN::Error::from_errno(EMFILE);
}
using FDWrapper = OpenFileDescriptorSet::FDWrapper;
FDWrapper::FDWrapper(BAN::RefPtr<OpenFileDescription> description)
: m_description(description)
{
if (m_description)
m_description->file.inode->on_clone(m_description->status_flags);
}
FDWrapper::~FDWrapper()
{
clear();
}
FDWrapper& FDWrapper::operator=(const FDWrapper& other)
{
clear();
m_description = other.m_description;
if (m_description)
m_description->file.inode->on_clone(m_description->status_flags);
return *this;
}
FDWrapper& FDWrapper::operator=(FDWrapper&& other)
{
clear();
m_description = BAN::move(other.m_description);
return *this;
}
void FDWrapper::clear()
{
if (m_description)
m_description->file.inode->on_close(m_description->status_flags);
}
BAN::ErrorOr<FDWrapper> OpenFileDescriptorSet::get_fd_wrapper(int fd)
{
LockGuard _(m_mutex);
TRY(validate_fd(fd));
return FDWrapper { m_open_files[fd].description };
}
size_t OpenFileDescriptorSet::open_all_fd_wrappers(BAN::Span<FDWrapper> fd_wrappers)
{
LockGuard _(m_mutex);
for (size_t i = 0; i < fd_wrappers.size(); i++)
{
auto fd_or_error = get_free_fd();
if (fd_or_error.is_error())
return i;
const int fd = fd_or_error.release_value();
m_open_files[fd].description = BAN::move(fd_wrappers[i].m_description);
m_open_files[fd].descriptor_flags = 0;
fd_wrappers[i].m_fd = fd;
}
return fd_wrappers.size();
}
}

View File

@ -161,7 +161,7 @@ namespace Kernel
if (executable.master_tls.has_value())
{
auto tls_result = TRY(process->initialize_thread_local_storage(process->page_table(), *executable.master_tls));
TRY(process->add_mapped_region(BAN::move(tls_result.region)));
TRY(process->m_mapped_regions.emplace_back(BAN::move(tls_result.region)));
tls_addr = tls_result.addr;
}
@ -173,15 +173,7 @@ namespace Kernel
auxiliary_vector.span()
));
if (tls_addr.has_value())
{
#if ARCH(x86_64)
thread->set_fsbase(*tls_addr);
#elif ARCH(i686)
thread->set_gsbase(*tls_addr);
#else
#error
#endif
}
thread->set_tls(*tls_addr);
process->add_thread(thread);
process->register_to_scheduler();
@ -313,17 +305,7 @@ namespace Kernel
child.status = __WGENEXITCODE(status, signal);
parent_process->add_pending_signal(SIGCHLD, {
.si_signo = SIGCHLD,
.si_code = signal ? CLD_KILLED : CLD_EXITED,
.si_errno = 0,
.si_pid = pid(),
.si_uid = m_credentials.ruid(),
.si_addr = nullptr,
.si_status = __WGENEXITCODE(status, signal),
.si_band = 0,
.si_value = {},
});
parent_process->add_pending_signal(SIGCHLD);
if (!parent_process->m_threads.empty())
Processor::scheduler().unblock_thread(parent_process->m_threads.front());
@ -338,7 +320,7 @@ namespace Kernel
LockGuard _(m_process_lock);
for (auto* thread : m_threads)
if (thread != &Thread::current())
thread->add_signal(SIGKILL, {});
thread->add_signal(SIGKILL);
}
while (m_threads.size() > 1)
@ -415,33 +397,6 @@ namespace Kernel
return result;
}
BAN::ErrorOr<void> Process::add_mapped_region(BAN::UniqPtr<MemoryRegion>&& region)
{
const size_t index = find_mapped_region(region->vaddr());
TRY(m_mapped_regions.insert(index, BAN::move(region)));
return {};
}
size_t Process::find_mapped_region(vaddr_t address) const
{
size_t l = 0, r = m_mapped_regions.size();
while (l < r)
{
const size_t mid = (l + r) / 2;
if (m_mapped_regions[mid]->contains(address))
return mid;
if (m_mapped_regions[mid]->vaddr() < address)
l = mid + 1;
else
r = mid;
}
return l;
}
size_t Process::proc_meminfo(off_t offset, BAN::ByteSpan buffer) const
{
ASSERT(offset >= 0);
@ -508,15 +463,7 @@ namespace Kernel
return read_from_vec_of_str(m_environ, offset, buffer);
}
BAN::ErrorOr<BAN::String> Process::proc_cwd() const
{
LockGuard _(m_process_lock);
BAN::String result;
TRY(result.append(m_working_directory.canonical_path));
return result;
}
BAN::ErrorOr<BAN::String> Process::proc_exe() const
BAN::ErrorOr<BAN::String> Process::proc_executable() const
{
LockGuard _(m_process_lock);
BAN::String result;
@ -540,7 +487,7 @@ namespace Kernel
{
ASSERT(m_process_lock.is_locked());
if (path && path[0] == '\0')
if (path[0] == '\0')
return BAN::Error::from_errno(ENOENT);
auto relative_parent = TRY(find_relative_parent(fd, path));
@ -783,13 +730,7 @@ namespace Kernel
{
auto tls_result = TRY(initialize_thread_local_storage(*new_page_table, *executable.master_tls));
TRY(new_mapped_regions.emplace_back(BAN::move(tls_result.region)));
#if ARCH(x86_64)
new_thread->set_fsbase(tls_result.addr);
#elif ARCH(i686)
new_thread->set_gsbase(tls_result.addr);
#else
#error
#endif
new_thread->set_tls(tls_result.addr);
}
// NOTE: this is done before disabling interrupts and moving the threads as
@ -1072,17 +1013,7 @@ namespace Kernel
if (current_ns < process->m_alarm_wake_time_ns)
break;
process->add_pending_signal(SIGALRM, {
.si_signo = SIGALRM,
.si_code = SI_TIMER,
.si_errno = 0,
.si_pid = 0,
.si_uid = 0,
.si_addr = nullptr,
.si_status = 0,
.si_band = 0,
.si_value = {},
});
process->add_pending_signal(SIGALRM);
ASSERT(!process->m_threads.empty());
Processor::scheduler().unblock_thread(process->m_threads.front());
@ -1146,15 +1077,14 @@ namespace Kernel
if (Thread::current().userspace_stack().contains(address))
return Thread::current().userspace_stack().allocate_page_for_demand_paging(address);
const size_t index = find_mapped_region(address);
if (index >= m_mapped_regions.size())
return false;
for (auto& region : m_mapped_regions)
{
if (!region->contains(address))
continue;
return region->allocate_page_containing(address, wants_write);
}
auto& region = m_mapped_regions[index];
if (!region->contains(address))
return false;
return region->allocate_page_containing(address, wants_write);
return false;
}
BAN::ErrorOr<long> Process::open_inode(VirtualFileSystem::File&& file, int flags)
@ -1302,27 +1232,6 @@ namespace Kernel
return 0;
}
BAN::ErrorOr<long> Process::sys_renameat(int oldfd, const char* old, int newfd, const char* _new)
{
LockGuard _(m_process_lock);
if (old != nullptr)
TRY(validate_string_access(old));
if (_new != nullptr)
TRY(validate_string_access(_new));
auto [old_parent, old_name] = TRY(find_parent_file(oldfd, old, O_WRONLY));
if (!old_parent.inode->mode().ifdir())
return BAN::Error::from_errno(ENOTDIR);
auto [new_parent, new_name] = TRY(find_parent_file(newfd, _new, O_WRONLY));
if (!new_parent.inode->mode().ifdir())
return BAN::Error::from_errno(ENOTDIR);
TRY(new_parent.inode->rename_inode(old_parent.inode, old_name, new_name));
return 0;
}
BAN::ErrorOr<long> Process::sys_unlinkat(int fd, const char* path, int flag)
{
if (flag && flag != AT_REMOVEDIR)
@ -1334,15 +1243,9 @@ namespace Kernel
auto [parent, file_name] = TRY(find_parent_file(fd, path, O_WRONLY));
const auto inode = TRY(parent.inode->find_inode(file_name));
if (inode->mode().ifdir() != (flag == AT_REMOVEDIR))
if (TRY(parent.inode->find_inode(file_name))->mode().ifdir() != (flag == AT_REMOVEDIR))
return BAN::Error::from_errno(flag ? EPERM : ENOTDIR);
if (parent.inode->mode().mode & Inode::Mode::ISVTX)
if (m_credentials.ruid() != parent.inode->uid() && m_credentials.ruid() != inode->uid())
return BAN::Error::from_errno(EPERM);
TRY(parent.inode->unlink(file_name));
return 0;
@ -1666,72 +1569,73 @@ namespace Kernel
return 0;
}
BAN::ErrorOr<long> Process::sys_recvmsg(int socket, msghdr* _message, int flags)
BAN::ErrorOr<long> Process::sys_sendto(const sys_sendto_t* _arguments)
{
msghdr message;
sys_sendto_t arguments;
{
LockGuard _(m_process_lock);
TRY(validate_pointer_access(_message, sizeof(msghdr), true));
message = *_message;
TRY(validate_pointer_access(_arguments, sizeof(sys_sendto_t), false));
arguments = *_arguments;
}
BAN::Vector<MemoryRegion*> regions;
BAN::ScopeGuard _([&regions] {
for (auto* region : regions)
if (region != nullptr)
region->unpin();
if (arguments.length == 0)
return BAN::Error::from_errno(EINVAL);
MemoryRegion* message_region = nullptr;
MemoryRegion* address_region = nullptr;
BAN::ScopeGuard _([&] {
if (message_region)
message_region->unpin();
if (address_region)
address_region->unpin();
});
if (message.msg_name)
TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_name, message.msg_namelen, true))));
if (message.msg_control)
TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_control, message.msg_controllen, true))));
if (message.msg_iov)
{
TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_iov, message.msg_iovlen * sizeof(iovec), true))));
for (int i = 0; i < message.msg_iovlen; i++)
TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_iov[i].iov_base, message.msg_iov[i].iov_len, true))));
}
message_region = TRY(validate_and_pin_pointer_access(arguments.message, arguments.length, false));
if (arguments.dest_addr)
address_region = TRY(validate_and_pin_pointer_access(arguments.dest_addr, arguments.dest_len, false));
auto ret = TRY(m_open_file_descriptors.recvmsg(socket, message, flags));
{
LockGuard _(m_process_lock);
TRY(validate_pointer_access(_message, sizeof(msghdr), true));
*_message = message;
}
return ret;
auto message = BAN::ConstByteSpan(static_cast<const uint8_t*>(arguments.message), arguments.length);
return TRY(m_open_file_descriptors.sendto(arguments.socket, message, arguments.dest_addr, arguments.dest_len));
}
BAN::ErrorOr<long> Process::sys_sendmsg(int socket, const msghdr* _message, int flags)
BAN::ErrorOr<long> Process::sys_recvfrom(sys_recvfrom_t* _arguments)
{
msghdr message;
sys_recvfrom_t arguments;
{
LockGuard _(m_process_lock);
TRY(validate_pointer_access(_message, sizeof(msghdr), false));
message = *_message;
TRY(validate_pointer_access(_arguments, sizeof(sys_sendto_t), false));
arguments = *_arguments;
}
BAN::Vector<MemoryRegion*> regions;
BAN::ScopeGuard _([&regions] {
for (auto* region : regions)
if (region != nullptr)
region->unpin();
if (!arguments.address != !arguments.address_len)
return BAN::Error::from_errno(EINVAL);
if (arguments.length == 0)
return BAN::Error::from_errno(EINVAL);
MemoryRegion* buffer_region = nullptr;
MemoryRegion* address_region1 = nullptr;
MemoryRegion* address_region2 = nullptr;
BAN::ScopeGuard _([&] {
if (buffer_region)
buffer_region->unpin();
if (address_region1)
address_region1->unpin();
if (address_region2)
address_region2->unpin();
});
if (message.msg_name)
TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_name, message.msg_namelen, false))));
if (message.msg_control)
TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_control, message.msg_controllen, false))));
if (message.msg_iov)
buffer_region = TRY(validate_and_pin_pointer_access(arguments.buffer, arguments.length, true));
if (arguments.address_len)
{
TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_iov, message.msg_iovlen * sizeof(iovec), false))));
for (int i = 0; i < message.msg_iovlen; i++)
TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_iov[i].iov_base, message.msg_iov[i].iov_len, false))));
address_region1 = TRY(validate_and_pin_pointer_access(arguments.address_len, sizeof(*arguments.address_len), true));
address_region2 = TRY(validate_and_pin_pointer_access(arguments.address, *arguments.address_len, true));
}
return TRY(m_open_file_descriptors.sendmsg(socket, message, flags));
auto message = BAN::ByteSpan(static_cast<uint8_t*>(arguments.buffer), arguments.length);
return TRY(m_open_file_descriptors.recvfrom(arguments.socket, message, arguments.address, arguments.address_len));
}
BAN::ErrorOr<long> Process::sys_ioctl(int fildes, int request, void* arg)
@ -2094,7 +1998,7 @@ namespace Kernel
return TRY(m_open_file_descriptors.dup2(fildes, fildes2));
}
BAN::ErrorOr<long> Process::sys_fcntl(int fildes, int cmd, uintptr_t extra)
BAN::ErrorOr<long> Process::sys_fcntl(int fildes, int cmd, int extra)
{
return TRY(m_open_file_descriptors.fcntl(fildes, cmd, extra));
}
@ -2286,38 +2190,6 @@ namespace Kernel
return 0;
}
BAN::ErrorOr<BAN::Vector<BAN::UniqPtr<MemoryRegion>>> Process::split_memory_region(BAN::UniqPtr<MemoryRegion>&& region, vaddr_t base, size_t length)
{
ASSERT(base % PAGE_SIZE == 0);
ASSERT(base < region->vaddr() + region->size());
if (auto rem = length % PAGE_SIZE)
length += PAGE_SIZE - rem;
if (base + length > region->vaddr() + region->size())
length = region->vaddr() + region->size() - base;
BAN::Vector<BAN::UniqPtr<MemoryRegion>> result;
TRY(result.reserve(3));
if (region->vaddr() < base)
{
auto temp = TRY(region->split(base - region->vaddr()));
MUST(result.push_back(BAN::move(region)));
region = BAN::move(temp);
}
if (base + length < region->vaddr() + region->size())
{
auto temp = TRY(region->split(base + length - region->vaddr()));
MUST(result.push_back(BAN::move(region)));
region = BAN::move(temp);
}
MUST(result.push_back(BAN::move(region)));
return result;
}
BAN::ErrorOr<long> Process::sys_mmap(const sys_mmap_t* user_args)
{
sys_mmap_t args;
@ -2330,9 +2202,6 @@ namespace Kernel
if (args.prot != PROT_NONE && (args.prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)))
return BAN::Error::from_errno(EINVAL);
if (!(args.flags & MAP_ANONYMOUS) && (args.off % PAGE_SIZE))
return BAN::Error::from_errno(EINVAL);
if (!(args.flags & MAP_PRIVATE) == !(args.flags & MAP_SHARED))
return BAN::Error::from_errno(EINVAL);
auto region_type = (args.flags & MAP_PRIVATE) ? MemoryRegion::Type::PRIVATE : MemoryRegion::Type::SHARED;
@ -2350,67 +2219,30 @@ namespace Kernel
else
page_flags |= PageTable::Flags::UserSupervisor;
LockGuard _(m_process_lock);
AddressRange address_range { .start = 0x400000, .end = USERSPACE_END };
if (args.flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))
if (args.flags & MAP_FIXED)
{
const vaddr_t vaddr = reinterpret_cast<vaddr_t>(args.addr);
if (vaddr == 0 || vaddr % PAGE_SIZE)
return BAN::Error::from_errno(EINVAL);
if (!PageTable::is_valid_pointer(vaddr))
return BAN::Error::from_errno(ENOMEM);
if (!PageTable::is_valid_pointer(vaddr + args.len))
return BAN::Error::from_errno(ENOMEM);
address_range = {
.start = vaddr,
.end = vaddr + args.len,
};
vaddr_t base_addr = reinterpret_cast<vaddr_t>(args.addr);
address_range.start = BAN::Math::div_round_up<vaddr_t>(base_addr, PAGE_SIZE) * PAGE_SIZE;
address_range.end = BAN::Math::div_round_up<vaddr_t>(base_addr + args.len, PAGE_SIZE) * PAGE_SIZE;
if (args.flags & MAP_FIXED_NOREPLACE)
;
else
for (size_t i = 0; i < m_mapped_regions.size(); i++)
{
const size_t first_index = find_mapped_region(vaddr);
for (size_t i = first_index; i < m_mapped_regions.size(); i++)
{
if (!m_mapped_regions[i]->overlaps(vaddr, args.len))
break;
m_mapped_regions[i]->wait_not_pinned();
auto temp = BAN::move(m_mapped_regions[i]);
m_mapped_regions.remove(i--);
if (temp->is_contained_by(vaddr, args.len))
continue;
auto new_regions = TRY(split_memory_region(BAN::move(temp), vaddr, args.len));
for (auto& new_region : new_regions)
if (!new_region->overlaps(vaddr, args.len))
TRY(m_mapped_regions.insert(++i, BAN::move(new_region)));
}
if (!m_mapped_regions[i]->overlaps(base_addr, args.len))
continue;
if (!m_mapped_regions[i]->contains_fully(base_addr, args.len))
derrorln("VERY BROKEN MAP_FIXED UNMAP");
m_mapped_regions[i]->wait_not_pinned();
m_mapped_regions.remove(i--);
}
}
else if (const vaddr_t vaddr = reinterpret_cast<vaddr_t>(args.addr); vaddr == 0)
;
else if (vaddr % PAGE_SIZE)
;
else if (!PageTable::is_valid_pointer(vaddr))
;
else if (!PageTable::is_valid_pointer(vaddr + args.len))
;
else if (!page_table().is_range_free(vaddr, args.len))
;
else
{
address_range = {
.start = vaddr,
.end = vaddr + args.len,
};
}
if (args.flags & MAP_ANONYMOUS)
{
if (args.off != 0)
return BAN::Error::from_errno(EINVAL);
auto region = TRY(MemoryBackedRegion::create(
page_table(),
args.len,
@ -2419,11 +2251,13 @@ namespace Kernel
O_EXEC | O_RDWR
));
const vaddr_t region_vaddr = region->vaddr();
TRY(add_mapped_region(BAN::move(region)));
return region_vaddr;
LockGuard _(m_process_lock);
TRY(m_mapped_regions.push_back(BAN::move(region)));
return m_mapped_regions.back()->vaddr();
}
LockGuard _(m_process_lock);
auto inode = TRY(m_open_file_descriptors.inode_of(args.fildes));
const auto status_flags = TRY(m_open_file_descriptors.status_flags_of(args.fildes));
@ -2433,10 +2267,10 @@ namespace Kernel
if ((args.prot & PROT_WRITE) && !(status_flags & O_WRONLY))
return BAN::Error::from_errno(EACCES);
BAN::UniqPtr<MemoryRegion> region;
BAN::UniqPtr<MemoryRegion> memory_region;
if (inode->mode().ifreg())
{
region = TRY(FileBackedRegion::create(
memory_region = TRY(FileBackedRegion::create(
inode,
page_table(),
args.off, args.len,
@ -2447,7 +2281,7 @@ namespace Kernel
}
else if (inode->is_device())
{
region = TRY(static_cast<Device&>(*inode).mmap_region(
memory_region = TRY(static_cast<Device&>(*inode).mmap_region(
page_table(),
args.off, args.len,
address_range,
@ -2456,12 +2290,11 @@ namespace Kernel
));
}
if (!region)
if (!memory_region)
return BAN::Error::from_errno(ENODEV);
const vaddr_t region_vaddr = region->vaddr();
TRY(add_mapped_region(BAN::move(region)));
return region_vaddr;
TRY(m_mapped_regions.push_back(BAN::move(memory_region)));
return m_mapped_regions.back()->vaddr();
}
BAN::ErrorOr<long> Process::sys_munmap(void* addr, size_t len)
@ -2469,35 +2302,31 @@ namespace Kernel
if (len == 0)
return BAN::Error::from_errno(EINVAL);
vaddr_t vaddr = reinterpret_cast<vaddr_t>(addr);
if (auto rem = vaddr % PAGE_SIZE)
{
vaddr -= rem;
len += rem;
}
const vaddr_t vaddr = reinterpret_cast<vaddr_t>(addr);
if (vaddr % PAGE_SIZE != 0)
return BAN::Error::from_errno(EINVAL);
if (auto rem = len % PAGE_SIZE)
len += PAGE_SIZE - rem;
LockGuard _(m_process_lock);
const size_t first_index = find_mapped_region(vaddr);
for (size_t i = first_index; i < m_mapped_regions.size(); i++)
// FIXME: We should unmap partial regions.
// This is a hack to only unmap if the whole mmap region
// is contained within [addr, addr + len]
for (size_t i = 0; i < m_mapped_regions.size(); i++)
{
if (!m_mapped_regions[i]->overlaps(vaddr, len))
break;
auto& region = m_mapped_regions[i];
m_mapped_regions[i]->wait_not_pinned();
auto temp = BAN::move(m_mapped_regions[i]);
m_mapped_regions.remove(i--);
if (temp->is_contained_by(vaddr, len))
continue;
auto new_regions = TRY(split_memory_region(BAN::move(temp), vaddr, len));
for (auto& new_region : new_regions)
if (!new_region->overlaps(vaddr, len))
TRY(m_mapped_regions.insert(++i, BAN::move(new_region)));
const vaddr_t region_s = region->vaddr();
const vaddr_t region_e = region->vaddr() + region->size();
if (vaddr <= region_s && region_e <= vaddr + len)
{
region->wait_not_pinned();
m_mapped_regions.remove(i--);
}
else if (region->overlaps(vaddr, len))
dwarnln("TODO: partial region munmap");
}
return 0;
@ -2530,35 +2359,38 @@ namespace Kernel
LockGuard _(m_process_lock);
const size_t first_index = find_mapped_region(vaddr);
for (size_t i = first_index; i < m_mapped_regions.size(); i++)
// FIXME: We should protect partial regions.
// This is a hack to only protect if the whole mmap region
// is contained within [addr, addr + len]
for (size_t i = 0; i < m_mapped_regions.size(); i++)
{
if (!m_mapped_regions[i]->overlaps(vaddr, len))
break;
if (!m_mapped_regions[i]->is_contained_by(vaddr, len))
{
m_mapped_regions[i]->wait_not_pinned();
auto temp = BAN::move(m_mapped_regions[i]);
m_mapped_regions.remove(i--);
auto new_regions = TRY(split_memory_region(BAN::move(temp), vaddr, len));
for (size_t j = 0; j < new_regions.size(); j++)
TRY(m_mapped_regions.insert(i + j + 1, BAN::move(new_regions[j])));
continue;
}
auto& region = m_mapped_regions[i];
const bool is_shared = (region->type() == MemoryRegion::Type::SHARED);
const bool is_writable = (region->status_flags() & O_WRONLY);
const bool want_write = (prot & PROT_WRITE);
if (is_shared && want_write && !is_writable)
return BAN::Error::from_errno(EACCES);
// NOTE: don't change protection of regions in use
region->wait_not_pinned();
TRY(region->mprotect(flags));
const vaddr_t region_s = region->vaddr();
const vaddr_t region_e = region->vaddr() + region->size();
if (vaddr <= region_s && region_e <= vaddr + len)
{
const bool is_shared = (region->type() == MemoryRegion::Type::SHARED);
const bool is_writable = (region->status_flags() & O_WRONLY);
const bool want_write = (prot & PROT_WRITE);
if (is_shared && want_write && !is_writable)
return BAN::Error::from_errno(EACCES);
// FIXME: if the region is pinned writable, this may
// cause some problems :D
TRY(region->mprotect(flags));
}
else if (region->overlaps(vaddr, len))
{
const bool is_shared = (region->type() == MemoryRegion::Type::SHARED);
const bool is_writable = (region->status_flags() & O_WRONLY);
const bool want_write = (prot & PROT_WRITE);
if (is_shared && want_write && !is_writable)
return BAN::Error::from_errno(EACCES);
dwarnln("TODO: partial region mprotect");
TRY(region->mprotect(flags | region->flags()));
}
}
return 0;
@ -2572,16 +2404,9 @@ namespace Kernel
LockGuard _(m_process_lock);
const vaddr_t vaddr = reinterpret_cast<vaddr_t>(addr);
const size_t first_index = find_mapped_region(vaddr);
for (size_t i = first_index; i < m_mapped_regions.size(); i++)
{
auto& region = *m_mapped_regions[i];
if (vaddr >= region.vaddr() + region.size())
break;
if (region.overlaps(vaddr, len))
TRY(region.msync(vaddr, len, flags));
}
for (auto& mapped_region : m_mapped_regions)
if (mapped_region->overlaps(vaddr, len))
TRY(mapped_region->msync(vaddr, len, flags));
return 0;
}
@ -2623,9 +2448,8 @@ namespace Kernel
auto region = TRY(SharedMemoryObjectManager::get().map_object(key, page_table(), { .start = 0x400000, .end = USERSPACE_END }));
LockGuard _(m_process_lock);
const vaddr_t region_vaddr = region->vaddr();
TRY(add_mapped_region(BAN::move(region)));
return region_vaddr;
TRY(m_mapped_regions.push_back(BAN::move(region)));
return m_mapped_regions.back()->vaddr();
}
BAN::ErrorOr<long> Process::sys_ttyname(int fildes, char* name, size_t namesize)
@ -2820,18 +2644,7 @@ namespace Kernel
if (!(m_signal_handlers[SIGCHLD].sa_flags & SA_NOCLDSTOP))
{
parent->add_pending_signal(SIGCHLD, {
.si_signo = SIGCHLD,
.si_code = stopped ? CLD_STOPPED : CLD_CONTINUED,
.si_errno = 0,
.si_pid = pid(),
.si_uid = m_credentials.ruid(),
.si_addr = nullptr,
.si_status = __WGENEXITCODE(0, signal),
.si_band = 0,
.si_value = { .sival_int = 0 },
});
parent->add_pending_signal(SIGCHLD);
if (!parent->m_threads.empty())
Processor::scheduler().unblock_thread(parent->m_threads.front());
}
@ -2857,7 +2670,7 @@ namespace Kernel
}
}
BAN::ErrorOr<void> Process::kill(pid_t pid, int signal, const siginfo_t& signal_info)
BAN::ErrorOr<void> Process::kill(pid_t pid, int signal)
{
if (pid == 0 || pid == -1)
return BAN::Error::from_errno(ENOTSUP);
@ -2881,7 +2694,7 @@ namespace Kernel
process.set_stopped(false, signal);
else
{
process.add_pending_signal(signal, signal_info);
process.add_pending_signal(signal);
if (!process.m_threads.empty())
Processor::scheduler().unblock_thread(process.m_threads.front());
process.m_stop_blocker.unblock();
@ -2903,18 +2716,6 @@ namespace Kernel
if (signal != 0 && (signal < _SIGMIN || signal > _SIGMAX))
return BAN::Error::from_errno(EINVAL);
const siginfo_t signal_info {
.si_signo = signal,
.si_code = SI_USER,
.si_errno = 0,
.si_pid = this->pid(),
.si_uid = m_credentials.ruid(),
.si_addr = nullptr,
.si_status = 0,
.si_band = 0,
.si_value = {},
};
if (pid == m_pid)
{
if (signal == 0)
@ -2925,13 +2726,13 @@ namespace Kernel
set_stopped(false, signal);
else
{
add_pending_signal(signal, signal_info);
add_pending_signal(signal);
m_stop_blocker.unblock();
}
return 0;
}
TRY(kill(pid, signal, signal_info));
TRY(kill(pid, signal));
return 0;
}
@ -3152,28 +2953,16 @@ namespace Kernel
return 0;
}
BAN::ErrorOr<long> Process::sys_set_fsbase(void* addr)
BAN::ErrorOr<long> Process::sys_set_tls(void* addr)
{
Thread::current().set_fsbase(reinterpret_cast<vaddr_t>(addr));
Processor::load_fsbase();
Thread::current().set_tls(reinterpret_cast<vaddr_t>(addr));
Processor::load_tls();
return 0;
}
BAN::ErrorOr<long> Process::sys_get_fsbase()
BAN::ErrorOr<long> Process::sys_get_tls()
{
return Thread::current().get_fsbase();
}
BAN::ErrorOr<long> Process::sys_set_gsbase(void* addr)
{
Thread::current().set_gsbase(reinterpret_cast<vaddr_t>(addr));
Processor::load_gsbase();
return 0;
}
BAN::ErrorOr<long> Process::sys_get_gsbase()
{
return Thread::current().get_gsbase();
return Thread::current().get_tls();
}
BAN::ErrorOr<long> Process::sys_pthread_create(const pthread_attr_t* attr, void (*entry)(void*), void* arg)
@ -3274,19 +3063,8 @@ namespace Kernel
{
if (thread->tid() != tid)
continue;
if (signal == 0)
return 0;
thread->add_signal(signal, {
.si_signo = signal,
.si_code = SI_USER,
.si_errno = 0,
.si_pid = pid(),
.si_uid = m_credentials.ruid(),
.si_addr = nullptr,
.si_status = 0,
.si_band = 0,
.si_value = {},
});
if (signal != 0)
thread->add_signal(signal);
return 0;
}
@ -3696,64 +3474,62 @@ namespace Kernel
return validate_pointer_access(str, strlen(str) + 1, false);
}
BAN::ErrorOr<void> Process::validate_pointer_access_check(const void* ptr, size_t size, bool needs_write)
{
ASSERT(&Process::current() == this);
const vaddr_t vaddr = reinterpret_cast<vaddr_t>(ptr);
// NOTE: detect overflow
if (vaddr + size < vaddr)
goto unauthorized_access;
// trying to access kernel space memory
if (vaddr + size > USERSPACE_END)
goto unauthorized_access;
for (const auto* thread : m_threads)
if (vaddr >= thread->userspace_stack_bottom() && vaddr + size <= thread->userspace_stack_top())
return {};
// FIXME: should we allow cross mapping access?
for (const auto& mapped_region : m_mapped_regions)
{
if (!mapped_region->contains_fully(vaddr, size))
continue;
if (needs_write && !mapped_region->writable())
goto unauthorized_access;
return {};
}
unauthorized_access:
dwarnln("process {}, thread {} attempted to make an invalid pointer access to 0x{H}->0x{H}", pid(), Thread::current().tid(), vaddr, vaddr + size);
Debug::dump_stack_trace();
MUST(sys_kill(pid(), SIGSEGV));
return BAN::Error::from_errno(EINTR);
}
BAN::ErrorOr<void> Process::validate_pointer_access(const void* ptr, size_t size, bool needs_write)
{
// TODO: This seems very slow as we loop over the range twice
if (size == 0)
return {};
const auto page_flags = (needs_write ? PageTable::Flags::ReadWrite : 0) | PageTable::Flags::Present;
TRY(validate_pointer_access_check(ptr, size, needs_write));
const vaddr_t vaddr = reinterpret_cast<vaddr_t>(ptr);
// Make sure all of the pages are mapped here, so demand paging does not happen
// while processing syscall.
const vaddr_t vaddr = reinterpret_cast<vaddr_t>(ptr);
const vaddr_t page_start = vaddr & PAGE_ADDR_MASK;
const size_t page_count = range_page_count(vaddr, size);
for (size_t i = 0; i < page_count; i++)
{
const vaddr_t current = page_start + i * PAGE_SIZE;
if ((page_table().get_page_flags(current) & page_flags) == page_flags)
if (page_table().get_page_flags(current) & PageTable::Flags::Present)
continue;
if (!TRY(Process::allocate_page_for_demand_paging(current, needs_write, false)))
{
const MemoryRegion* region_ptr = nullptr;
for (const auto& region : m_mapped_regions)
{
if (!region->contains(vaddr + i * PAGE_SIZE))
continue;
region_ptr = region.ptr();
break;
}
dwarnln("{} pid {}, tid {} made an invalid {} access to 0x{h}",
name(),
pid(),
Thread::current().tid(),
needs_write ? "write" : "read",
vaddr + i * PAGE_SIZE
);
dwarnln(" 0x{h}->0x{h}", vaddr, vaddr + size);
if (region_ptr == nullptr)
dwarnln(" no mapping covers this page");
else
{
dwarnln(" inside region 0x{h}->0x{h} {}{}{}",
region_ptr->vaddr(),
region_ptr->vaddr() + region_ptr->size(),
(region_ptr->flags() & PageTable::Flags::Present) ? 'r' : '-',
(region_ptr->flags() & PageTable::Flags::ReadWrite) ? 'w' : '-',
(region_ptr->flags() & PageTable::Flags::Execute) ? 'x' : '-'
);
}
page_table().debug_dump();
Debug::dump_stack_trace();
MUST(sys_kill(pid(), SIGSEGV));
return BAN::Error::from_errno(EINTR);
}
TRY(Process::allocate_page_for_demand_paging(current, needs_write, false));
}
return {};
@ -3763,24 +3539,14 @@ namespace Kernel
{
LockGuard _(m_process_lock);
TRY(validate_pointer_access(ptr, size, needs_write));
// FIXME: make stack MemoryRegion?
// FIXME: allow pinning multiple regions
const vaddr_t vaddr = reinterpret_cast<vaddr_t>(ptr);
const size_t first_index = find_mapped_region(vaddr);
for (size_t i = first_index; i < m_mapped_regions.size(); i++)
for (auto& region : m_mapped_regions)
{
auto& region = m_mapped_regions[i];
if (vaddr >= region->vaddr() + region->size())
break;
if (!region->contains_fully(vaddr, size))
if (!region->contains_fully(reinterpret_cast<vaddr_t>(ptr), size))
continue;
region->pin();
return region.ptr();
}
// FIXME: Make stack MemoryRegion?
return nullptr;
}

View File

@ -12,7 +12,6 @@ namespace Kernel
#if ARCH(x86_64)
static constexpr uint32_t MSR_IA32_FS_BASE = 0xC0000100;
static constexpr uint32_t MSR_IA32_GS_BASE = 0xC0000101;
static constexpr uint32_t MSR_IA32_KERNEL_GS_BASE = 0xC0000102;
#endif
ProcessorID Processor::s_bsp_id { PROCESSOR_NONE };
@ -266,52 +265,15 @@ namespace Kernel
set_interrupt_state(state);
}
void Processor::load_segments()
void Processor::load_tls()
{
{
const auto addr = scheduler().current_thread().get_fsbase();
#if ARCH(x86_64)
uint32_t ptr_hi = addr >> 32;
uint32_t ptr_lo = addr & 0xFFFFFFFF;
asm volatile("wrmsr" :: "d"(ptr_hi), "a"(ptr_lo), "c"(MSR_IA32_FS_BASE));
#elif ARCH(i686)
gdt().set_fsbase(addr);
#endif
}
{
const auto addr = scheduler().current_thread().get_gsbase();
#if ARCH(x86_64)
uint32_t ptr_hi = addr >> 32;
uint32_t ptr_lo = addr & 0xFFFFFFFF;
asm volatile("wrmsr" :: "d"(ptr_hi), "a"(ptr_lo), "c"(MSR_IA32_KERNEL_GS_BASE));
#elif ARCH(i686)
gdt().set_gsbase(addr);
#endif
}
}
void Processor::load_fsbase()
{
const auto addr = scheduler().current_thread().get_fsbase();
const auto addr = scheduler().current_thread().get_tls();
#if ARCH(x86_64)
uint32_t ptr_hi = addr >> 32;
uint32_t ptr_lo = addr & 0xFFFFFFFF;
asm volatile("wrmsr" :: "d"(ptr_hi), "a"(ptr_lo), "c"(MSR_IA32_FS_BASE));
#elif ARCH(i686)
gdt().set_fsbase(addr);
#endif
}
void Processor::load_gsbase()
{
const auto addr = scheduler().current_thread().get_gsbase();
#if ARCH(x86_64)
uint32_t ptr_hi = addr >> 32;
uint32_t ptr_lo = addr & 0xFFFFFFFF;
asm volatile("wrmsr" :: "d"(ptr_hi), "a"(ptr_lo), "c"(MSR_IA32_KERNEL_GS_BASE));
#elif ARCH(i686)
gdt().set_gsbase(addr);
gdt().set_tls(addr);
#endif
}

View File

@ -282,8 +282,7 @@ namespace Kernel
}
Processor::gdt().set_tss_stack(thread->kernel_stack_top());
if (thread->is_userspace())
Processor::load_segments();
Processor::load_tls();
*interrupt_stack = thread->interrupt_stack();
*interrupt_registers = thread->interrupt_registers();

View File

@ -124,8 +124,8 @@ namespace Kernel
case SYS_WAIT:
case SYS_ACCEPT:
case SYS_CONNECT:
case SYS_RECVMSG:
case SYS_SENDMSG:
case SYS_RECVFROM:
case SYS_SENDTO:
case SYS_FLOCK:
return true;
default:

View File

@ -417,11 +417,6 @@ namespace Kernel
m_cursor_shown = (ch == 'h');
return reset_ansi();
}
if (m_ansi_state.question && m_ansi_state.nums[0] == 2004)
{
// bracketed paste mode, there is no pasting so this is a no-op
return reset_ansi();
}
reset_ansi();
dprintln_if(DEBUG_VTTY, "Unsupported ANSI CSI character {}", static_cast<char>(ch));
return;

View File

@ -328,8 +328,7 @@ namespace Kernel
thread->m_kernel_stack = TRY(m_kernel_stack->clone(new_process->page_table()));
thread->m_userspace_stack = TRY(m_userspace_stack->clone(new_process->page_table()));
thread->m_fsbase = m_fsbase;
thread->m_gsbase = m_gsbase;
thread->m_tls = m_tls;
thread->m_state = State::NotStarted;
@ -386,7 +385,7 @@ namespace Kernel
vaddr_t vaddr = userspace_stack_top() - needed_size;
const size_t page_count = BAN::Math::div_round_up<size_t>(needed_size, PAGE_SIZE);
const size_t page_count = BAN::Math::div_round_up(needed_size, PAGE_SIZE);
for (size_t i = 0; i < page_count; i++)
TRY(m_userspace_stack->allocate_page_for_demand_paging(vaddr + i * PAGE_SIZE));
@ -550,14 +549,12 @@ namespace Kernel
vaddr_t signal_handler;
{
SpinLockGuard _(m_process->m_signal_lock);
const auto& handler = m_process->m_signal_handlers[i];
signal_handler = (handler.sa_flags & SA_SIGINFO)
? reinterpret_cast<vaddr_t>(handler.sa_sigaction)
: reinterpret_cast<vaddr_t>(handler.sa_handler);
ASSERT(!(m_process->m_signal_handlers[i].sa_flags & SA_SIGINFO));
signal_handler = (vaddr_t)m_process->m_signal_handlers[i].sa_handler;
}
if (signal_handler == reinterpret_cast<vaddr_t>(SIG_IGN))
if (signal_handler == (vaddr_t)SIG_IGN)
continue;
if (signal_handler == reinterpret_cast<vaddr_t>(SIG_DFL) && is_default_ignored_signal(i))
if (signal_handler == (vaddr_t)SIG_DFL && is_default_ignored_signal(i))
continue;
return true;
}
@ -588,7 +585,7 @@ namespace Kernel
return false;
}
bool Thread::handle_signal(int signal, const siginfo_t& _signal_info)
bool Thread::handle_signal(int signal)
{
ASSERT(&Thread::current() == this);
ASSERT(is_userspace());
@ -598,23 +595,16 @@ namespace Kernel
auto& interrupt_stack = *reinterpret_cast<InterruptStack*>(kernel_stack_top() - sizeof(InterruptStack));
ASSERT(GDT::is_user_segment(interrupt_stack.cs));
auto signal_info = _signal_info;
if (signal == 0)
{
const uint64_t process_signal_pending_mask = process().signal_pending_mask();
const uint64_t full_pending_mask = m_signal_pending_mask | process_signal_pending_mask;
uint64_t full_pending_mask = m_signal_pending_mask | process().signal_pending_mask();
for (signal = _SIGMIN; signal <= _SIGMAX; signal++)
{
const uint64_t mask = 1ull << signal;
uint64_t mask = 1ull << signal;
if ((full_pending_mask & mask) && !(m_signal_block_mask & mask))
break;
}
ASSERT(signal <= _SIGMAX);
if (process_signal_pending_mask & (1ull << signal))
signal_info = process().m_signal_infos[signal];
else
signal_info = m_signal_infos[signal];
}
else
{
@ -625,19 +615,18 @@ namespace Kernel
vaddr_t signal_handler;
bool has_sa_restart;
vaddr_t signal_stack_top = 0;
{
SpinLockGuard _(m_process->m_signal_lock);
auto& handler = m_process->m_signal_handlers[signal];
signal_handler = (handler.sa_flags & SA_SIGINFO)
? reinterpret_cast<vaddr_t>(handler.sa_sigaction)
: reinterpret_cast<vaddr_t>(handler.sa_handler);
has_sa_restart = !!(handler.sa_flags & SA_RESTART);
ASSERT(!(handler.sa_flags & SA_SIGINFO));
signal_handler = reinterpret_cast<vaddr_t>(handler.sa_handler);
if (handler.sa_flags & SA_RESETHAND)
handler = { .sa_handler = SIG_DFL, .sa_mask = 0, .sa_flags = 0 };
handler.sa_handler = SIG_DFL;
has_sa_restart = !!(handler.sa_flags & SA_RESTART);
const auto& alt_stack = m_signal_alt_stack;
if (alt_stack.ss_flags != SS_DISABLE && (handler.sa_flags & SA_ONSTACK) && !currently_on_alternate_stack())
@ -672,15 +661,15 @@ namespace Kernel
if (signal_stack_top == 0)
{
pages[0] = (interrupt_stack.sp - 1 * sizeof(uintptr_t) ) & PAGE_ADDR_MASK;
pages[1] = (interrupt_stack.sp - 5 * sizeof(uintptr_t) - sizeof(siginfo_t)) & PAGE_ADDR_MASK;
pages[0] = (interrupt_stack.sp - 1 * sizeof(uintptr_t)) & PAGE_ADDR_MASK;
pages[1] = (interrupt_stack.sp - 5 * sizeof(uintptr_t)) & PAGE_ADDR_MASK;
page_count = 2;
}
else
{
pages[0] = (interrupt_stack.sp - 1 * sizeof(uintptr_t) ) & PAGE_ADDR_MASK;
pages[2] = (signal_stack_top - 1 * sizeof(uintptr_t) ) & PAGE_ADDR_MASK;
pages[1] = (signal_stack_top - 4 * sizeof(uintptr_t) - sizeof(siginfo_t)) & PAGE_ADDR_MASK;
pages[0] = (interrupt_stack.sp - sizeof(uintptr_t)) & PAGE_ADDR_MASK;
pages[1] = (signal_stack_top - 4 * sizeof(uintptr_t)) & PAGE_ADDR_MASK;
pages[2] = (signal_stack_top - 1 * sizeof(uintptr_t)) & PAGE_ADDR_MASK;
page_count = 3;
}
@ -701,16 +690,6 @@ namespace Kernel
interrupt_stack.sp = signal_stack_top;
write_to_stack(interrupt_stack.sp, old_stack);
write_to_stack(interrupt_stack.sp, interrupt_stack.flags);
{
signal_info.si_signo = signal;
signal_info.si_addr = reinterpret_cast<void*>(interrupt_stack.ip);
interrupt_stack.sp -= sizeof(siginfo_t);
*reinterpret_cast<siginfo_t*>(interrupt_stack.sp) = signal_info;
static_assert(sizeof(siginfo_t) % sizeof(uintptr_t) == 0);
}
write_to_stack(interrupt_stack.sp, signal);
write_to_stack(interrupt_stack.sp, signal_handler);
interrupt_stack.ip = (uintptr_t)signal_trampoline;
@ -748,29 +727,25 @@ namespace Kernel
return has_sa_restart;
}
void Thread::add_signal(int signal, const siginfo_t& info)
void Thread::add_signal(int signal)
{
SpinLockGuard _(m_signal_lock);
if (m_process)
{
vaddr_t signal_handler;
{
SpinLockGuard _(m_process->m_signal_lock);
const auto& handler = m_process->m_signal_handlers[signal];
signal_handler = (handler.sa_flags & SA_SIGINFO)
? reinterpret_cast<vaddr_t>(handler.sa_sigaction)
: reinterpret_cast<vaddr_t>(handler.sa_handler);
ASSERT(!(m_process->m_signal_handlers[signal].sa_flags & SA_SIGINFO));
signal_handler = (vaddr_t)m_process->m_signal_handlers[signal].sa_handler;
}
if (signal_handler == reinterpret_cast<vaddr_t>(SIG_IGN))
if (signal_handler == (vaddr_t)SIG_IGN)
return;
if (signal_handler == reinterpret_cast<vaddr_t>(SIG_DFL) && is_default_ignored_signal(signal))
if (signal_handler == (vaddr_t)SIG_DFL && is_default_ignored_signal(signal))
return;
}
const uint64_t mask = 1ull << signal;
m_signal_pending_mask |= mask;
m_signal_infos[signal] = info;
if (this != &Thread::current())
Processor::scheduler().unblock_thread(this);

View File

@ -113,18 +113,6 @@ namespace Kernel
auto& operational = operational_regs();
if (auto page_size_bits = operational.pagesize & 0xFFFF; page_size_bits != 1)
{
dwarnln("XHCI does not support 4096 byte pages");
dwarnln(" supported page sizes:");
for (size_t i = 0; i < 16; i++)
if (page_size_bits & (1 << i))
dwarnln(" {} bytes", 1 << (12 + i));
if (__builtin_popcount(page_size_bits) != 1)
dwarnln(" ... XHCI spec only allows a single supported page size???");
return BAN::Error::from_errno(ENOTSUP);
}
// allocate and program dcbaa
m_dcbaa_region = TRY(DMARegion::create(capabilities.hcsparams1.max_slots * 8));
memset(reinterpret_cast<void*>(m_dcbaa_region->vaddr()), 0, m_dcbaa_region->size());
@ -301,9 +289,6 @@ namespace Kernel
const paddr_t paddr = Heap::get().take_free_page();
if (paddr == 0)
return BAN::Error::from_errno(ENOMEM);
PageTable::with_fast_page(paddr, [] {
memset(PageTable::fast_page_as_ptr(), 0, PAGE_SIZE);
});
m_scratchpad_buffers[i] = paddr;
scratchpad_buffer_array[i] = paddr;
}

View File

@ -11,6 +11,7 @@
#include <kernel/IDT.h>
#include <kernel/Input/PS2/Controller.h>
#include <kernel/InterruptController.h>
#include <kernel/kprint.h>
#include <kernel/Memory/Heap.h>
#include <kernel/Memory/kmalloc.h>
#include <kernel/Memory/PageTable.h>

View File

@ -179,7 +179,6 @@ const char* strerrordesc_np(int error)
case EWOULDBLOCK: return "Operation would block.";
case EXDEV: return "Cross-device link.";
case ENOTBLK: return "Block device required";
case ESHUTDOWN: return "Cannot send after transport endpoint shutdown.";
case EUNKNOWN: return "Unknown error";
}
return nullptr;

1
ports/.gitignore vendored
View File

@ -1,4 +1,3 @@
*/*
!*/patches/
!*/build.sh
.installed_ports

View File

@ -1,6 +1,6 @@
diff -ruN SDL2-2.32.8/cmake/sdlplatform.cmake SDL2-2.32.8-banan_os/cmake/sdlplatform.cmake
--- SDL2-2.32.8/cmake/sdlplatform.cmake 2024-08-14 13:35:43.000000000 +0300
+++ SDL2-2.32.8-banan_os/cmake/sdlplatform.cmake 2025-11-22 00:45:00.922311100 +0200
+++ SDL2-2.32.8-banan_os/cmake/sdlplatform.cmake 2025-08-06 02:07:18.347821313 +0300
@@ -28,6 +28,8 @@
set(SDL_CMAKE_PLATFORM AIX)
elseif(CMAKE_SYSTEM_NAME MATCHES "Minix.*")
@ -12,7 +12,7 @@ diff -ruN SDL2-2.32.8/cmake/sdlplatform.cmake SDL2-2.32.8-banan_os/cmake/sdlplat
endif()
diff -ruN SDL2-2.32.8/CMakeLists.txt SDL2-2.32.8-banan_os/CMakeLists.txt
--- SDL2-2.32.8/CMakeLists.txt 2025-06-03 02:00:39.000000000 +0300
+++ SDL2-2.32.8-banan_os/CMakeLists.txt 2025-11-22 00:45:00.923441418 +0200
+++ SDL2-2.32.8-banan_os/CMakeLists.txt 2025-08-06 02:19:44.864415796 +0300
@@ -14,7 +14,7 @@
set(SDL2_SUBPROJECT ON)
endif()
@ -55,7 +55,7 @@ diff -ruN SDL2-2.32.8/CMakeLists.txt SDL2-2.32.8-banan_os/CMakeLists.txt
+ file(GLOB VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/banan_os/*.cpp)
+ list(APPEND SOURCE_FILES ${VIDEO_SOURCES})
+ set(HAVE_SDL_VIDEO TRUE)
+ list(APPEND EXTRA_LIBS gui input clipboard)
+ list(APPEND EXTRA_LIBS gui input)
+
+ if(SDL_OPENGL)
+ set(SDL_VIDEO_OPENGL 1)
@ -91,7 +91,7 @@ diff -ruN SDL2-2.32.8/CMakeLists.txt SDL2-2.32.8-banan_os/CMakeLists.txt
file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/riscos/*.c)
diff -ruN SDL2-2.32.8/include/SDL_config.h.cmake SDL2-2.32.8-banan_os/include/SDL_config.h.cmake
--- SDL2-2.32.8/include/SDL_config.h.cmake 2025-01-01 17:47:53.000000000 +0200
+++ SDL2-2.32.8-banan_os/include/SDL_config.h.cmake 2025-11-22 00:45:00.924001549 +0200
+++ SDL2-2.32.8-banan_os/include/SDL_config.h.cmake 2025-08-06 02:01:21.085539504 +0300
@@ -307,6 +307,7 @@
#cmakedefine SDL_AUDIO_DRIVER_FUSIONSOUND @SDL_AUDIO_DRIVER_FUSIONSOUND@
#cmakedefine SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC @SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC@
@ -110,7 +110,7 @@ diff -ruN SDL2-2.32.8/include/SDL_config.h.cmake SDL2-2.32.8-banan_os/include/SD
#cmakedefine SDL_VIDEO_DRIVER_DIRECTFB @SDL_VIDEO_DRIVER_DIRECTFB@
diff -ruN SDL2-2.32.8/include/SDL_platform.h SDL2-2.32.8-banan_os/include/SDL_platform.h
--- SDL2-2.32.8/include/SDL_platform.h 2025-01-01 17:47:53.000000000 +0200
+++ SDL2-2.32.8-banan_os/include/SDL_platform.h 2025-11-22 00:45:00.924303894 +0200
+++ SDL2-2.32.8-banan_os/include/SDL_platform.h 2025-08-06 02:01:21.085701327 +0300
@@ -36,6 +36,10 @@
#undef __HAIKU__
#define __HAIKU__ 1
@ -124,7 +124,7 @@ diff -ruN SDL2-2.32.8/include/SDL_platform.h SDL2-2.32.8-banan_os/include/SDL_pl
#define __BSDI__ 1
diff -ruN SDL2-2.32.8/src/audio/banan_os/SDL_banan_os_audio.cpp SDL2-2.32.8-banan_os/src/audio/banan_os/SDL_banan_os_audio.cpp
--- SDL2-2.32.8/src/audio/banan_os/SDL_banan_os_audio.cpp 1970-01-01 02:00:00.000000000 +0200
+++ SDL2-2.32.8-banan_os/src/audio/banan_os/SDL_banan_os_audio.cpp 2025-11-22 00:45:00.924702550 +0200
+++ SDL2-2.32.8-banan_os/src/audio/banan_os/SDL_banan_os_audio.cpp 2025-08-06 02:01:21.085876490 +0300
@@ -0,0 +1,150 @@
+/*
+ Simple DirectMedia Layer
@ -278,7 +278,7 @@ diff -ruN SDL2-2.32.8/src/audio/banan_os/SDL_banan_os_audio.cpp SDL2-2.32.8-bana
+#endif
diff -ruN SDL2-2.32.8/src/audio/banan_os/SDL_banan_os_audio.h SDL2-2.32.8-banan_os/src/audio/banan_os/SDL_banan_os_audio.h
--- SDL2-2.32.8/src/audio/banan_os/SDL_banan_os_audio.h 1970-01-01 02:00:00.000000000 +0200
+++ SDL2-2.32.8-banan_os/src/audio/banan_os/SDL_banan_os_audio.h 2025-11-22 00:45:00.924820303 +0200
+++ SDL2-2.32.8-banan_os/src/audio/banan_os/SDL_banan_os_audio.h 2025-08-06 02:01:21.085937043 +0300
@@ -0,0 +1,34 @@
+/*
+ Simple DirectMedia Layer
@ -316,7 +316,7 @@ diff -ruN SDL2-2.32.8/src/audio/banan_os/SDL_banan_os_audio.h SDL2-2.32.8-banan_
+};
diff -ruN SDL2-2.32.8/src/audio/SDL_audio.c SDL2-2.32.8-banan_os/src/audio/SDL_audio.c
--- SDL2-2.32.8/src/audio/SDL_audio.c 2025-01-01 17:47:53.000000000 +0200
+++ SDL2-2.32.8-banan_os/src/audio/SDL_audio.c 2025-11-22 00:45:00.925178591 +0200
+++ SDL2-2.32.8-banan_os/src/audio/SDL_audio.c 2025-08-06 02:01:21.086082872 +0300
@@ -87,6 +87,9 @@
#ifdef SDL_AUDIO_DRIVER_HAIKU
&HAIKUAUDIO_bootstrap,
@ -329,7 +329,7 @@ diff -ruN SDL2-2.32.8/src/audio/SDL_audio.c SDL2-2.32.8-banan_os/src/audio/SDL_a
#endif
diff -ruN SDL2-2.32.8/src/audio/SDL_sysaudio.h SDL2-2.32.8-banan_os/src/audio/SDL_sysaudio.h
--- SDL2-2.32.8/src/audio/SDL_sysaudio.h 2025-01-01 17:47:53.000000000 +0200
+++ SDL2-2.32.8-banan_os/src/audio/SDL_sysaudio.h 2025-11-22 00:45:00.925759535 +0200
+++ SDL2-2.32.8-banan_os/src/audio/SDL_sysaudio.h 2025-08-06 02:01:21.086309718 +0300
@@ -196,6 +196,7 @@
extern AudioBootStrap WINMM_bootstrap;
extern AudioBootStrap PAUDIO_bootstrap;
@ -340,7 +340,7 @@ diff -ruN SDL2-2.32.8/src/audio/SDL_sysaudio.h SDL2-2.32.8-banan_os/src/audio/SD
extern AudioBootStrap DUMMYAUDIO_bootstrap;
diff -ruN SDL2-2.32.8/src/misc/banan_os/SDL_sysurl.cpp SDL2-2.32.8-banan_os/src/misc/banan_os/SDL_sysurl.cpp
--- SDL2-2.32.8/src/misc/banan_os/SDL_sysurl.cpp 1970-01-01 02:00:00.000000000 +0200
+++ SDL2-2.32.8-banan_os/src/misc/banan_os/SDL_sysurl.cpp 2025-11-22 00:45:00.926117334 +0200
+++ SDL2-2.32.8-banan_os/src/misc/banan_os/SDL_sysurl.cpp 2025-08-06 02:01:21.086457363 +0300
@@ -0,0 +1,30 @@
+/*
+ Simple DirectMedia Layer
@ -372,111 +372,9 @@ diff -ruN SDL2-2.32.8/src/misc/banan_os/SDL_sysurl.cpp SDL2-2.32.8-banan_os/src/
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_clipboard.cpp SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_clipboard.cpp
--- SDL2-2.32.8/src/video/banan_os/SDL_banan_os_clipboard.cpp 1970-01-01 02:00:00.000000000 +0200
+++ SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_clipboard.cpp 2025-11-22 01:10:01.840984523 +0200
@@ -0,0 +1,51 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifdef SDL_VIDEO_DRIVER_BANANOS
+
+#include "SDL_banan_os_clipboard.h"
+
+#include <LibClipboard/Clipboard.h>
+
+int BANANOS_SetClipboardText(_THIS, const char *text) {
+ if (LibClipboard::Clipboard::set_clipboard_text(text).is_error())
+ return -1;
+ return 0;
+}
+
+char *BANANOS_GetClipboardText(_THIS) {
+ auto text_or_error = LibClipboard::Clipboard::get_clipboard_text();
+ if (text_or_error.is_error())
+ return NULL;
+ return SDL_strdup(text_or_error.value().data());
+}
+
+SDL_bool BANANOS_HasClipboardText(_THIS) {
+ auto text_or_error = LibClipboard::Clipboard::get_clipboard_text();
+ if (text_or_error.is_error())
+ return SDL_FALSE;
+ return text_or_error.value().empty() ? SDL_FALSE : SDL_TRUE;
+}
+
+#endif /* SDL_VIDEO_DRIVER_BANANOS */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_clipboard.h SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_clipboard.h
--- SDL2-2.32.8/src/video/banan_os/SDL_banan_os_clipboard.h 1970-01-01 02:00:00.000000000 +0200
+++ SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_clipboard.h 2025-11-22 01:10:16.932880273 +0200
@@ -0,0 +1,43 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_BANANOS_CLIPBOARD_H
+#define SDL_BANANOS_CLIPBOARD_H
+
+#include "../../SDL_internal.h"
+
+#include "../SDL_sysvideo.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int BANANOS_SetClipboardText(_THIS, const char *text);
+extern char *BANANOS_GetClipboardText(_THIS);
+extern SDL_bool BANANOS_HasClipboardText(_THIS);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/* vi: set ts=4 sw=4 expandtab: */
diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_message_box.cpp SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_message_box.cpp
--- SDL2-2.32.8/src/video/banan_os/SDL_banan_os_message_box.cpp 1970-01-01 02:00:00.000000000 +0200
+++ SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_message_box.cpp 2025-11-22 00:45:00.926337964 +0200
+++ SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_message_box.cpp 2025-08-06 02:01:21.086557935 +0300
@@ -0,0 +1,60 @@
+/*
+ Simple DirectMedia Layer
@ -540,7 +438,7 @@ diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_message_box.cpp SDL2-2.32.
+/* vi: set ts=4 sw=4 expandtab: */
diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_message_box.h SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_message_box.h
--- SDL2-2.32.8/src/video/banan_os/SDL_banan_os_message_box.h 1970-01-01 02:00:00.000000000 +0200
+++ SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_message_box.h 2025-11-22 00:45:00.926434625 +0200
+++ SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_message_box.h 2025-08-06 02:01:21.086603053 +0300
@@ -0,0 +1,45 @@
+/*
+ Simple DirectMedia Layer
@ -589,8 +487,8 @@ diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_message_box.h SDL2-2.32.8-
+/* vi: set ts=4 sw=4 expandtab: */
diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_video.cpp
--- SDL2-2.32.8/src/video/banan_os/SDL_banan_os_video.cpp 1970-01-01 02:00:00.000000000 +0200
+++ SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_video.cpp 2025-11-22 01:08:26.204647073 +0200
@@ -0,0 +1,729 @@
+++ SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_video.cpp 2025-08-21 02:32:59.649175565 +0300
@@ -0,0 +1,724 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
@ -620,7 +518,6 @@ diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.32.8-bana
+#include "../../events/SDL_events_c.h"
+}
+
+#include "SDL_banan_os_clipboard.h"
+#include "SDL_banan_os_message_box.h"
+
+#include <BAN/Debug.h>
@ -1302,10 +1199,6 @@ diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.32.8-bana
+ device->GL_MakeCurrent = BANANOS_GL_MakeCurrent;
+ device->GL_SwapWindow = BANANOS_GL_SwapWindow;
+
+ device->SetClipboardText = BANANOS_SetClipboardText;
+ device->GetClipboardText = BANANOS_GetClipboardText;
+ device->HasClipboardText = BANANOS_HasClipboardText;
+
+ device->free = BANANOS_free;
+
+ return device;
@ -1322,7 +1215,7 @@ diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.32.8-bana
+/* vi: set ts=4 sw=4 expandtab: */
diff -ruN SDL2-2.32.8/src/video/SDL_sysvideo.h SDL2-2.32.8-banan_os/src/video/SDL_sysvideo.h
--- SDL2-2.32.8/src/video/SDL_sysvideo.h 2025-05-20 00:24:41.000000000 +0300
+++ SDL2-2.32.8-banan_os/src/video/SDL_sysvideo.h 2025-11-22 00:45:00.927152737 +0200
+++ SDL2-2.32.8-banan_os/src/video/SDL_sysvideo.h 2025-08-06 02:01:21.086873550 +0300
@@ -462,6 +462,7 @@
extern VideoBootStrap WINDOWS_bootstrap;
extern VideoBootStrap WINRT_bootstrap;
@ -1333,7 +1226,7 @@ diff -ruN SDL2-2.32.8/src/video/SDL_sysvideo.h SDL2-2.32.8-banan_os/src/video/SD
extern VideoBootStrap Android_bootstrap;
diff -ruN SDL2-2.32.8/src/video/SDL_video.c SDL2-2.32.8-banan_os/src/video/SDL_video.c
--- SDL2-2.32.8/src/video/SDL_video.c 2025-05-20 00:24:41.000000000 +0300
+++ SDL2-2.32.8-banan_os/src/video/SDL_video.c 2025-11-22 00:45:00.928264617 +0200
+++ SDL2-2.32.8-banan_os/src/video/SDL_video.c 2025-08-06 02:01:21.087224294 +0300
@@ -96,6 +96,9 @@
#ifdef SDL_VIDEO_DRIVER_HAIKU
&HAIKU_bootstrap,

View File

@ -1,23 +0,0 @@
#!/bin/bash ../install.sh
NAME='SDL2_image'
VERSION='2.8.8'
DOWNLOAD_URL="https://github.com/libsdl-org/SDL_image/releases/download/release-$VERSION/SDL2_image-$VERSION.tar.gz#2213b56fdaff2220d0e38c8e420cbe1a83c87374190cba8c70af2156097ce30a"
DEPENDENCIES=('SDL2' 'libpng' 'libjpeg' 'libtiff' 'libwebp')
configure() {
$BANAN_CMAKE --fresh -S . -B build -G Ninja \
--toolchain="$BANAN_TOOLCHAIN_DIR/Toolchain.txt" \
-DCMAKE_INSTALL_PREFIX='/usr' \
-DCMAKE_BUILD_TYPE=Release \
-DSDL2IMAGE_AVIF=OFF \
|| exit 1
}
build() {
$BANAN_CMAKE --build build || exit 1
}
install() {
$BANAN_CMAKE --install build || exit 1
}

View File

@ -1,8 +0,0 @@
#!/bin/bash ../install.sh
NAME='SDL_mixer'
VERSION='1.2.12'
DOWNLOAD_URL="https://github.com/libsdl-org/SDL_mixer/archive/refs/tags/release-$VERSION.tar.gz#4176dfc887664419bfd16c41013c6cf0c48eca6b95ae3c34205630e8a7a94faa"
TAR_CONTENT="SDL_mixer-release-$VERSION"
CONFIG_SUB=('build-scripts/config.sub')
DEPENDENCIES=('libmikmod' 'libiconv' 'sdl12-compat')

View File

@ -1,31 +0,0 @@
diff -ruN SDL_mixer-1.2.12/configure SDL_mixer-1.2.12-banan_os/configure
--- SDL_mixer-1.2.12/configure 2012-01-16 00:00:28.000000000 +0200
+++ SDL_mixer-1.2.12-banan_os/configure 2025-11-16 03:27:17.615555034 +0200
@@ -4073,6 +4073,10 @@
lt_cv_deplibs_check_method=pass_all
;;
+banan_os*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
beos*)
lt_cv_deplibs_check_method=pass_all
;;
@@ -9083,6 +9087,16 @@
esac
;;
+banan_os*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker="$host_os DynamicLoader.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
beos*)
library_names_spec='${libname}${shared_ext}'
dynamic_linker="$host_os ld.so"

View File

@ -1,32 +0,0 @@
#!/bin/bash ../install.sh
NAME='SuperTux'
VERSION='0.6.3'
DOWNLOAD_URL="https://github.com/SuperTux/supertux/releases/download/v$VERSION/SuperTux-v$VERSION-Source.tar.gz#f7940e6009c40226eb34ebab8ffb0e3a894892d891a07b35d0e5762dd41c79f6"
TAR_CONTENT="SuperTux-v$VERSION-Source"
DEPENDENCIES=('boost' 'SDL2' 'SDL2_image' 'curl' 'openal-soft' 'libvorbis' 'freetype' 'physfs' 'glm')
configure() {
mkdir -p build
pushd build
$BANAN_CMAKE \
--toolchain="$BANAN_TOOLCHAIN_DIR/Toolchain.txt" \
-G Ninja --fresh .. \
-DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_BUILD_TYPE=Release \
-DINSTALL_SUBDIR_BIN=bin \
-DBUILD_DOCUMENTATION=OFF \
-DENABLE_OPENGL=OFF \
-DENABLE_BOOST_STATIC_LIBS=ON \
|| exit 1
popd
# crashes in `std::ostream::sentry::sentry(std::ostream&)` with shared boost
}
build() {
$BANAN_CMAKE --build build || exit 1
}
install() {
$BANAN_CMAKE --install build || exit 1
}

View File

@ -1,52 +0,0 @@
diff -ruN SuperTux-0.6.3/CMakeLists.txt SuperTux-0.6.3-banan_os/CMakeLists.txt
--- SuperTux-0.6.3/CMakeLists.txt 2021-12-23 01:01:57.000000000 +0200
+++ SuperTux-0.6.3-banan_os/CMakeLists.txt 2025-11-02 20:57:03.725932455 +0200
@@ -171,7 +171,7 @@
else(ENABLE_BOOST_STATIC_LIBS)
set(Boost_USE_STATIC_LIBS FALSE)
endif(ENABLE_BOOST_STATIC_LIBS)
-find_package(Boost REQUIRED COMPONENTS filesystem system date_time locale)
+find_package(Boost REQUIRED COMPONENTS filesystem date_time locale)
include_directories(SYSTEM ${Boost_INCLUDE_DIR})
link_directories(${Boost_LIBRARY_DIRS})
@@ -507,6 +507,7 @@
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
-DCMAKE_INSTALL_PREFIX=${SQUIRREL_PREFIX}
+ -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
-DINSTALL_INC_DIR=include
-DCMAKE_POSITION_INDEPENDENT_CODE=ON)
@@ -966,7 +967,7 @@
endif()
endif()
target_include_directories(supertux2_lib SYSTEM PUBLIC ${SDL_TTF_PREFIX}/include/SDL2)
-target_link_libraries(supertux2_lib PUBLIC SDL_ttf_lib)
+target_link_libraries(supertux2_lib PUBLIC libSDL2_ttf.a)
if(VCPKG_BUILD)
target_link_libraries(supertux2_lib PUBLIC freetype)
else()
@@ -977,9 +978,10 @@
target_link_libraries(supertux2_lib PUBLIC ${HARFBUZZ_LIBRARY} ${FRIBIDI_LIBRARY} ${RAQM_LIBRARY})
endif()
-target_link_libraries(supertux2_lib PUBLIC squirrel_lib)
-target_link_libraries(supertux2_lib PUBLIC sqstdlib_lib)
-target_link_libraries(supertux2_lib PUBLIC tinygettext_lib)
+target_link_libraries(supertux2_lib PUBLIC libsquirrel_static.a)
+target_link_libraries(supertux2_lib PUBLIC libsqstdlib_static.a)
+target_link_libraries(supertux2_lib PUBLIC libtinygettext.a)
+
target_link_libraries(supertux2_lib PUBLIC sexp)
target_link_libraries(supertux2_lib PUBLIC savepng)
target_link_libraries(supertux2_lib PUBLIC partio_zip_lib)
@@ -1025,7 +1027,7 @@
if(VCPKG_BUILD)
target_link_libraries(supertux2_lib PUBLIC ${CURL_LIBRARIES})
else()
- target_link_libraries(supertux2_lib PUBLIC ${CURL_LIBRARY})
+ target_link_libraries(supertux2_lib PUBLIC ${CURL_LIBRARY} ssl crypto zstd z)
endif()
endif(HAVE_LIBCURL)
endif(NOT EMSCRIPTEN)

View File

@ -1,11 +0,0 @@
diff -ruN SuperTux-0.6.3/external/partio_zip/zip_manager.hpp SuperTux-0.6.3-banan_os/external/partio_zip/zip_manager.hpp
--- SuperTux-0.6.3/external/partio_zip/zip_manager.hpp 2021-12-23 01:01:58.000000000 +0200
+++ SuperTux-0.6.3-banan_os/external/partio_zip/zip_manager.hpp 2025-11-02 20:16:29.691656288 +0200
@@ -44,6 +44,7 @@
#include <fstream>
#include <iostream>
#include <map>
+#include <memory>
#include <string>
#include <stdexcept>
#include <vector>

View File

@ -1,8 +1,8 @@
#!/bin/bash ../install.sh
NAME='binutils'
VERSION='2.45'
DOWNLOAD_URL="https://ftpmirror.gnu.org/gnu/binutils/binutils-$VERSION.tar.gz#8a3eb4b10e7053312790f21ee1a38f7e2bbd6f4096abb590d3429e5119592d96"
VERSION='2.44'
DOWNLOAD_URL="https://ftpmirror.gnu.org/gnu/binutils/binutils-$VERSION.tar.gz#0cdd76777a0dfd3dd3a63f215f030208ddb91c2361d2bcc02acec0f1c16b6a2e"
DEPENDENCIES=('zlib' 'zstd')
MAKE_INSTALL_TARGETS=('install-strip')
CONFIGURE_OPTIONS=(
@ -22,3 +22,12 @@ pre_configure() {
unset PKG_CONFIG_LIBDIR
unset PKG_CONFIG_PATH
}
post_install() {
# remove libtool files
rm -f $BANAN_SYSROOT/usr/lib/libbfd.la
rm -f $BANAN_SYSROOT/usr/lib/libctf.la
rm -f $BANAN_SYSROOT/usr/lib/libctf-nobfd.la
rm -f $BANAN_SYSROOT/usr/lib/libopcodes.la
rm -f $BANAN_SYSROOT/usr/lib/libsframe.la
}

View File

@ -0,0 +1 @@
../../../toolchain/binutils-2.44.patch

View File

@ -1 +0,0 @@
../../../toolchain/binutils-2.45.patch

View File

@ -1,25 +0,0 @@
#!/bin/bash ../install.sh
NAME='boost'
VERSION='1.89.0'
DOWNLOAD_URL="https://archives.boost.io/release/$VERSION/source/boost_${VERSION//./_}.tar.gz#9de758db755e8330a01d995b0a24d09798048400ac25c03fc5ea9be364b13c93"
TAR_CONTENT="boost_${VERSION//./_}"
DEPENDENCIES=('zlib' 'zstd' 'libiconv')
configure() {
# stacktrace fails on multiple definition of __cxa_allocate_exception because our libstdc++ is static
./bootstrap.sh \
--prefix="$BANAN_SYSROOT/usr" \
--without-icu \
--without-libraries='python,stacktrace' \
|| exit 1
echo "using gcc : : $CXX ;" > user-config.jam
}
build() {
./b2 --user-config=user-config.jam toolset=gcc target-os=banan_os || exit 1
}
install() {
./b2 --user-config=user-config.jam toolset=gcc target-os=banan_os install || exit 1
}

View File

@ -1,115 +0,0 @@
diff -ruN boost_1_89_0/boost/config/detail/select_platform_config.hpp boost_1_89_0-banan_os/boost/config/detail/select_platform_config.hpp
--- boost_1_89_0/boost/config/detail/select_platform_config.hpp 2025-08-06 21:49:08.000000000 +0300
+++ boost_1_89_0-banan_os/boost/config/detail/select_platform_config.hpp 2025-10-29 21:16:39.964658105 +0200
@@ -93,6 +93,10 @@
// Web assembly:
# define BOOST_PLATFORM_CONFIG "boost/config/platform/wasm.hpp"
+#elif defined (__banan_os__)
+// banan-os:
+# define BOOST_PLATFORM_CONFIG "boost/config/platform/banan-os.hpp"
+
#else
# if defined(unix) \
@@ -139,6 +143,7 @@
# include "boost/config/platform/symbian.hpp"
# include "boost/config/platform/cray.hpp"
# include "boost/config/platform/vms.hpp"
+# include "boost/config/platform/banan-os.hpp"
# include <boost/config/detail/posix_features.hpp>
diff -ruN boost_1_89_0/boost/config/platform/banan-os.hpp boost_1_89_0-banan_os/boost/config/platform/banan-os.hpp
--- boost_1_89_0/boost/config/platform/banan-os.hpp 1970-01-01 02:00:00.000000000 +0200
+++ boost_1_89_0-banan_os/boost/config/platform/banan-os.hpp 2025-10-29 21:21:58.791813238 +0200
@@ -0,0 +1,29 @@
+// (C) Copyright Oskari Alaranta 2025.
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for most recent version.
+
+// banan-os specific config options:
+
+#define BOOST_PLATFORM "banan-os"
+
+#define BOOST_HAS_UNISTD_H
+#define BOOST_HAS_STDINT_H
+
+#ifndef BOOST_DISABLE_THREADS
+# define BOOST_HAS_THREADS
+#endif
+
+//
+// thread API's not auto detected:
+//
+#define BOOST_HAS_SCHED_YIELD
+#define BOOST_HAS_GETTIMEOFDAY
+
+// boilerplate code:
+#include <boost/config/detail/posix_features.hpp>
+
+
+
diff -ruN boost_1_89_0/tools/build/src/tools/features/os-feature.jam boost_1_89_0-banan_os/tools/build/src/tools/features/os-feature.jam
--- boost_1_89_0/tools/build/src/tools/features/os-feature.jam 2025-08-06 21:49:15.000000000 +0300
+++ boost_1_89_0-banan_os/tools/build/src/tools/features/os-feature.jam 2025-10-29 21:14:14.978467634 +0200
@@ -11,7 +11,7 @@
none
aix android appletv bsd cygwin darwin freebsd haiku hpux iphone linux
netbsd openbsd osf qnx qnxnto sgi solaris unix unixware windows vms vxworks
- freertos
+ freertos banan_os
# Not actually an OS -- used for targeting bare metal where object
# format is ELF. This catches both -elf and -eabi gcc targets as well
@@ -80,7 +80,7 @@
*Allowed values:* `aix`, `android`, `appletv`, `bsd`, `cygwin`, `darwin`,
`freebsd`, `haiku`, `hpux`, `iphone`, `linux`, `netbsd`, `openbsd`, `osf`,
`qnx`, `qnxnto`, `sgi`, `solaris`, `unix`, `unixware`, `windows`, `vms`,
-`vxworks`, `freertos`.
+`vxworks`, `freertos`, `banan_os`.
+
Specifies the operating system for which the code is to be generated. The
compiler you used should be the compiler for that operating system. This option
diff -ruN boost_1_89_0/tools/build/src/tools/gcc.jam boost_1_89_0-banan_os/tools/build/src/tools/gcc.jam
--- boost_1_89_0/tools/build/src/tools/gcc.jam 2025-08-06 21:49:15.000000000 +0300
+++ boost_1_89_0-banan_os/tools/build/src/tools/gcc.jam 2025-10-29 21:12:59.730889504 +0200
@@ -204,6 +204,7 @@
case *linux* : target-os ?= linux ;
case *aix* : target-os ?= aix ;
case *hpux* : target-os ?= hpux ;
+ case *banan_os* : target-os ?= banan_os ;
# TODO: finish this list.
}
}
@@ -406,6 +407,7 @@
threading-flags <target-os>cygwin/<threadapi>pthread : -pthread ;
threading-flags <target-os>solaris : -pthreads : rt ;
threading-flags <target-os>qnx : -pthread ;
+ threading-flags <target-os>banan_os : -pthread ;
local bsd = [ MATCH ^(.*bsd)$ : $(all-os) ] ;
threading-flags <target-os>$(bsd) : -pthread ;
@@ -413,7 +415,7 @@
# iOS doesn't need pthread flag according to the https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/pthread.3.html
# The default system libraries include pthread functions. No additional libraries or CFLAGS are necessary to use this API.
local no-threading = android beos haiku sgi darwin vxworks iphone appletv ;
- local threading-generic-os = [ set.difference $(all-os) : $(no-threading) $(bsd) windows cygwin solaris qnx ] ;
+ local threading-generic-os = [ set.difference $(all-os) : $(no-threading) $(bsd) windows cygwin solaris qnx banan_os ] ;
threading-flags <target-os>$(threading-generic-os) : -pthread : rt ;
}
diff -ruN boost_1_89_0/tools/build/src/tools/python.jam boost_1_89_0-banan_os/tools/build/src/tools/python.jam
--- boost_1_89_0/tools/build/src/tools/python.jam 2025-08-06 21:49:15.000000000 +0300
+++ boost_1_89_0-banan_os/tools/build/src/tools/python.jam 2025-10-29 21:09:10.276185725 +0200
@@ -667,6 +667,7 @@
case darwin : return ;
case windows : return ;
case haiku : return ;
+ case banan_os : return ;
case hpux : return <library>rt ;
case *bsd : return <library>pthread <toolset>gcc:<library>util ;

View File

@ -18,3 +18,8 @@ CONFIGURE_OPTIONS=(
'--with-ca-bundle=/etc/ssl/certs/ca-certificates.crt'
'--without-ca-path'
)
post_install() {
# remove libtool file
rm -f $BANAN_SYSROOT/usr/lib/libcurl.la
}

View File

@ -4,3 +4,8 @@ NAME='expat'
VERSION='2.7.1'
DOWNLOAD_URL="https://github.com/libexpat/libexpat/releases/download/R_2_7_1/expat-$VERSION.tar.gz#0cce2e6e69b327fc607b8ff264f4b66bdf71ead55a87ffd5f3143f535f15cfa2"
CONFIG_SUB=('conftools/config.sub')
post_install() {
# remove libtool file
rm -f $BANAN_SYSROOT/usr/lib/libexpat.la
}

View File

@ -3,8 +3,13 @@
NAME='freetype'
VERSION='2.13.3'
DOWNLOAD_URL="https://download.savannah.gnu.org/releases/freetype/freetype-$VERSION.tar.gz#5c3a8e78f7b24c20b25b54ee575d6daa40007a5f4eea2845861c3409b3021747"
DEPENDENCIES=('zlib' 'libpng')
CONFIG_SUB=('builds/unix/config.sub')
CONFIGURE_OPTIONS=(
'lt_cv_deplibs_check_method=pass_all'
)
post_install() {
# remove libtool file
rm -f $BANAN_SYSROOT/usr/lib/libfreetype.la
}

View File

@ -27,3 +27,10 @@ build() {
make -j$(nproc) all-target-libgcc CFLAGS_FOR_TARGET="$xcflags" || exit 1
make -j$(nproc) all-target-libstdc++-v3 || exit 1
}
post_install() {
# remove libtool files
rm -f $BANAN_SYSROOT/usr/lib/libstdc++.la
rm -f $BANAN_SYSROOT/usr/lib/libstdc++exp.la
rm -f $BANAN_SYSROOT/usr/lib/libsupc++.la
}

View File

@ -1,23 +0,0 @@
#!/bin/bash ../install.sh
NAME='glm'
VERSION='1.0.2'
DOWNLOAD_URL="https://github.com/g-truc/glm/archive/refs/tags/$VERSION.tar.gz#19edf2e860297efab1c74950e6076bf4dad9de483826bc95e2e0f2c758a43f65"
configure() {
$BANAN_CMAKE \
--toolchain="$BANAN_TOOLCHAIN_DIR/Toolchain.txt" \
-B build -G Ninja --fresh . \
-DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_BUILD_TYPE=Release \
-DGLM_BUILD_TESTS=OFF \
|| exit 1
}
build() {
$BANAN_CMAKE --build build || exit 1
}
install() {
$BANAN_CMAKE --install build || exit 1
}

View File

@ -7,3 +7,8 @@ CONFIG_SUB=('configfsf.sub')
CONFIGURE_OPTIONS=(
'CFLAGS=-std=c17'
)
post_install() {
# remove libtool file
rm -f $BANAN_SYSROOT/usr/lib/libgmp.la
}

View File

@ -11,12 +11,6 @@ fi
source "$BANAN_ROOT_DIR/script/config.sh"
installed_file="$BANAN_PORT_DIR/.installed_ports"
if [ -z $DONT_REMOVE_INSTALLED ]; then
export DONT_REMOVE_INSTALLED=1
rm -f "$installed_file"
fi
export PATH="$BANAN_TOOLCHAIN_PREFIX/bin:$PATH"
export PKG_CONFIG_DIR=''
@ -35,6 +29,10 @@ export OBJDUMP="$BANAN_TOOLCHAIN_TRIPLE-objdump"
export STRIP="$BANAN_TOOLCHAIN_TRIPLE-strip"
export CXXFILT="$BANAN_TOOLCHAIN_TRIPLE-c++filt"
pushd "$BANAN_ROOT_DIR" >/dev/null
./bos all && ./bos install || exit 1
popd >/dev/null
if [ "$BANAN_ARCH" = "i686" ]; then
export LDFLAGS="-shared-libgcc"
fi
@ -80,17 +78,13 @@ post_configure() {
}
configure() {
pre_configure
configure_options=("--host=$BANAN_ARCH-pc-banan_os" '--prefix=/usr')
configure_options+=("${CONFIGURE_OPTIONS[@]}")
./configure "${configure_options[@]}" || exit 1
}
pre_build() {
:
}
post_build() {
:
post_configure
}
build() {
@ -108,9 +102,13 @@ post_install() {
}
install() {
pre_install
for target in "${MAKE_INSTALL_TARGETS[@]}"; do
make $target "DESTDIR=$BANAN_SYSROOT" || exit 1
done
post_install
}
source $1
@ -120,30 +118,7 @@ if [ -z $NAME ] || [ -z $VERSION ] || [ -z $DOWNLOAD_URL ]; then
exit 1
fi
build_dir="$NAME-$VERSION-$BANAN_ARCH"
if [ ! -d "$build_dir" ]; then
rm -f '.compile_hash'
fi
if [ ! -f '.compile_hash' ] && [ -f "$installed_file" ]; then
sed -i "/^$NAME-$VERSION$/d" "$installed_file"
fi
if grep -qsxF "$NAME-$VERSION" "$installed_file"; then
exit 0
fi
pushd "$BANAN_ROOT_DIR" >/dev/null
./bos all && ./bos install || exit 1
popd >/dev/null
for dependency in "${DEPENDENCIES[@]}"; do
if [ ! -d "../$dependency" ]; then
echo "Could not find dependency '$dependency' or port '$NAME'"
exit 1
fi
pushd "../$dependency" >/dev/null
pwd
if ! ./build.sh; then
@ -153,6 +128,12 @@ for dependency in "${DEPENDENCIES[@]}"; do
popd >/dev/null
done
build_dir="$NAME-$VERSION-$BANAN_ARCH"
if [ ! -d "$build_dir" ]; then
rm -f ".compile_hash"
fi
if [ "$VERSION" = "git" ]; then
regex="(.*/.*\.git)#(.*)"
@ -205,7 +186,7 @@ else
exit 1
fi
regex='(.*\.tar\..*|.*\.tgz)'
regex='(.*\.tar\..*)'
if [[ $FILE_NAME =~ $regex ]] && [ ! -d "$build_dir" ]; then
tar xf "$FILE_NAME" || exit 1
@ -238,20 +219,9 @@ cd "$build_dir"
if (( $needs_compile )); then
config_sub_update
pre_configure
configure
post_configure
pre_build
build
post_build
sha256sum "$BANAN_SYSROOT/usr/lib/libc.a" > "../.compile_hash"
fi
pre_install
install
grep -qsxF "$NAME-$VERSION" "$installed_file" || echo "$NAME-$VERSION" >> "$installed_file"
post_install
find "$BANAN_SYSROOT/usr/lib" -name '*.la' -delete

View File

@ -4,3 +4,8 @@ NAME='libffi'
VERSION='3.5.2'
DOWNLOAD_URL="https://github.com/libffi/libffi/releases/download/v$VERSION/libffi-$VERSION.tar.gz#f3a3082a23b37c293a4fcd1053147b371f2ff91fa7ea1b2a52e335676bac82dc"
CONFIG_SUB=('config.sub')
post_install() {
# remove libtool file
rm -f $BANAN_SYSROOT/usr/lib/libffi.la
}

View File

@ -12,3 +12,9 @@ CONFIGURE_OPTIONS=(
pre_configure() {
echo '#include_next <sys/types.h>' > srclib/sys_types.in.h
}
post_install() {
# remove libtool file
rm -f $BANAN_SYSROOT/usr/lib/libcharset.la
rm -f $BANAN_SYSROOT/usr/lib/libiconv.la
}

View File

@ -5,3 +5,8 @@ VERSION='9f'
DOWNLOAD_URL="https://www.ijg.org/files/jpegsrc.v9f.tar.gz#04705c110cb2469caa79fb71fba3d7bf834914706e9641a4589485c1f832565b"
TAR_CONTENT="jpeg-$VERSION"
CONFIG_SUB=('config.sub')
post_install() {
# remove libtool files
rm -f $BANAN_SYSROOT/usr/lib/libjpeg.la
}

View File

@ -1,6 +0,0 @@
#!/bin/bash ../install.sh
NAME='libmikmod'
VERSION='3.3.13'
DOWNLOAD_URL="https://sourceforge.net/projects/mikmod/files/libmikmod/$VERSION/libmikmod-$VERSION.tar.gz#9fc1799f7ea6a95c7c5882de98be85fc7d20ba0a4a6fcacae11c8c6b382bb207"
CONFIG_SUB=('autotools/config.sub')

View File

@ -1,31 +0,0 @@
diff -ruN libmikmod-3.3.13/configure libmikmod-3.3.13-banan_os/configure
--- libmikmod-3.3.13/configure 2025-04-20 04:55:10.000000000 +0300
+++ libmikmod-3.3.13-banan_os/configure 2025-11-16 03:32:52.087690874 +0200
@@ -5962,6 +5962,10 @@
lt_cv_deplibs_check_method=pass_all
;;
+banan_os*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
beos*)
lt_cv_deplibs_check_method=pass_all
;;
@@ -11733,6 +11737,16 @@
esac
;;
+banan_os*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker="$host_os DynamicLoader.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
beos*)
library_names_spec='$libname$shared_ext'
dynamic_linker="$host_os ld.so"

View File

@ -1,6 +0,0 @@
#!/bin/bash ../install.sh
NAME='libogg'
VERSION='1.3.6'
DOWNLOAD_URL="https://github.com/xiph/ogg/releases/download/v$VERSION/libogg-$VERSION.tar.gz#83e6704730683d004d20e21b8f7f55dcb3383cdf84c0daedf30bde175f774638"
CONFIG_SUB=('config.sub')

View File

@ -1,20 +0,0 @@
diff -ruN libogg-1.3.6/configure libogg-1.3.6-banan_os/configure
--- libogg-1.3.6/configure 2025-06-16 19:02:25.000000000 +0300
+++ libogg-1.3.6-banan_os/configure 2025-10-31 22:25:25.050050235 +0200
@@ -10622,6 +10622,16 @@
esac
;;
+banan_os*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker="$host_os DynamicLoader.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
beos*)
library_names_spec='$libname$shared_ext'
dynamic_linker="$host_os ld.so"

View File

@ -5,3 +5,9 @@ VERSION='1.6.48'
DOWNLOAD_URL="https://download.sourceforge.net/libpng/libpng-$VERSION.tar.gz#68f3d83a79d81dfcb0a439d62b411aa257bb4973d7c67cd1ff8bdf8d011538cd"
DEPENDENCIES=('zlib')
CONFIG_SUB=('config.sub')
post_install() {
# remove libtool files
rm -f $BANAN_SYSROOT/usr/lib/libpng.la
rm -f $BANAN_SYSROOT/usr/lib/libpng16.la
}

View File

@ -1,10 +0,0 @@
#!/bin/bash ../install.sh
NAME='libsndfile'
VERSION='1.2.2'
DOWNLOAD_URL="https://github.com/libsndfile/libsndfile/releases/download/$VERSION/libsndfile-$VERSION.tar.xz#3799ca9924d3125038880367bf1468e53a1b7e3686a934f098b7e1d286cdb80e"
_DEPENDENCIES=('ca-certificates' 'openssl' 'zlib' 'zstd')
CONFIG_SUB=('build-aux/config.sub')
CONFIGURE_OPTIONS=(
'CFLAGS=-std=c11'
)

View File

@ -1,48 +0,0 @@
diff -ruN libsndfile-1.2.2/configure libsndfile-1.2.2-banan_os/configure
--- libsndfile-1.2.2/configure 2023-08-13 12:22:03.000000000 +0300
+++ libsndfile-1.2.2-banan_os/configure 2025-08-09 21:50:50.046135494 +0300
@@ -10059,6 +10059,10 @@
lt_cv_deplibs_check_method=pass_all
;;
+banan_os*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
beos*)
lt_cv_deplibs_check_method=pass_all
;;
@@ -15720,6 +15724,16 @@
esac
;;
+banan_os*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker="$host_os DynamicLoader.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
beos*)
library_names_spec='$libname$shared_ext'
dynamic_linker="$host_os ld.so"
@@ -19754,6 +19768,16 @@
esac
;;
+banan_os*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker="$host_os DynamicLoader.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
beos*)
library_names_spec='$libname$shared_ext'
dynamic_linker="$host_os ld.so"

View File

@ -6,3 +6,9 @@ DOWNLOAD_URL="https://download.osgeo.org/libtiff/tiff-$VERSION.tar.gz#67160e3457
TAR_CONTENT="tiff-$VERSION"
DEPENDENCIES=('zlib' 'zstd' 'libjpeg')
CONFIG_SUB=('config/config.sub')
post_install() {
# remove libtool files
rm -f $BANAN_SYSROOT/usr/lib/libtiff.la
rm -f $BANAN_SYSROOT/usr/lib/libtiffxx.la
}

Some files were not shown because too many files have changed in this diff Show More