diff --git a/apps/src/memeater.c b/apps/src/memeater.c index 875d319b..8e683637 100644 --- a/apps/src/memeater.c +++ b/apps/src/memeater.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -13,5 +14,6 @@ int main() printf("Allocating 4 MB of memory... %lx\n", (unsigned long)allocated); sleep(1); } while ((allocated = malloc(CHUNK))); - printf("Out of memory.\n"); + printf("Out of memory. (errno=%d)\n", errno); + printf("Press any key to restart.\n"); } \ No newline at end of file diff --git a/kernel/include/errno.h b/kernel/include/errno.h new file mode 100644 index 00000000..c02a1dcd --- /dev/null +++ b/kernel/include/errno.h @@ -0,0 +1,5 @@ +#pragma once + +#define EPERM 1 +#define ENOMEM 12 +#define EINVAL 22 \ No newline at end of file diff --git a/kernel/src/sys/mem.cpp b/kernel/src/sys/mem.cpp index f87843c6..148bb964 100644 --- a/kernel/src/sys/mem.cpp +++ b/kernel/src/sys/mem.cpp @@ -1,17 +1,20 @@ #define MODULE "mem" +#include "errno.h" #include "interrupts/Context.h" #include "log/Log.h" #include "memory/MemoryManager.h" #include "memory/VMM.h" #include +#define MAP_FAIL(errno) 0xffffffffffffff00 | (unsigned char)(errno) + void sys_mmap(Context* context, void* address, size_t size, int flags) { if (size < 4096) { kdbgln("sys_mmap: size too small"); - context->rax = 0; + context->rax = MAP_FAIL(EINVAL); return; } int real_flags = MAP_USER; @@ -23,7 +26,7 @@ void sys_mmap(Context* context, void* address, size_t size, int flags) if (kernelVMM.getPhysical((uint64_t)address) != (uint64_t)-1) // Address is already used. { kdbgln("attempt to mmap an already mapped address"); - context->rax = 0; + context->rax = MAP_FAIL(ENOMEM); return; } uint64_t offset = (uint64_t)address % 4096; @@ -37,7 +40,7 @@ void sys_mmap(Context* context, void* address, size_t size, int flags) else { kdbgln("mmap failed"); - context->rax = 0; + context->rax = MAP_FAIL(ENOMEM); return; } } @@ -52,7 +55,7 @@ void sys_mmap(Context* context, void* address, size_t size, int flags) else { kdbgln("mmap failed"); - context->rax = 0; + context->rax = MAP_FAIL(ENOMEM); return; } } @@ -60,17 +63,23 @@ void sys_mmap(Context* context, void* address, size_t size, int flags) void sys_munmap(Context* context, void* address, size_t size) { kdbgln("sys_munmap: attempting to unmap %lx", (uint64_t)address); + if (size < 4096) + { + kdbgln("munmap failed: size is too small"); + context->rax = -EINVAL; + return; + } if (!address) { kdbgln("munmap failed: attempted to unmap page 0"); - context->rax = -1; + context->rax = -EINVAL; return; } uint64_t flags = kernelVMM.getFlags((uint64_t)address); if (!(flags & MAP_USER)) { kdbgln("munmap failed: attempted to unmap a kernel page"); - context->rax = -1; + context->rax = -EINVAL; return; } uint64_t offset = (uint64_t)address % 4096; diff --git a/kernel/src/sys/paint.cpp b/kernel/src/sys/paint.cpp index 9a56de2a..daece6cd 100644 --- a/kernel/src/sys/paint.cpp +++ b/kernel/src/sys/paint.cpp @@ -1,4 +1,5 @@ #include "bootboot.h" +#include "errno.h" #include "interrupts/Context.h" #include "render/Framebuffer.h" #include @@ -9,12 +10,12 @@ void sys_paint(Context* context, uint64_t x, uint64_t y, uint64_t w, uint64_t h, { if ((x + w) > bootboot.fb_width) { - context->rax = -1; + context->rax = -EINVAL; return; } if ((y + h) > bootboot.fb_height) { - context->rax = -1; + context->rax = -EINVAL; return; } diff --git a/kernel/src/sys/version.cpp b/kernel/src/sys/version.cpp index 62a53c1c..f8bd51a3 100644 --- a/kernel/src/sys/version.cpp +++ b/kernel/src/sys/version.cpp @@ -1,8 +1,19 @@ #include "config.h" +#include "errno.h" #include "interrupts/Context.h" #include "std/stdio.h" void sys_getversion(Context* context, char* buffer, size_t max) { + if (!max) + { + context->rax = -EINVAL; + return; + } + if (!buffer) + { + context->rax = -EINVAL; + return; + } context->rax = snprintf(buffer, max, "moon %s", moon_version()); } \ No newline at end of file diff --git a/libs/libc/include/bits/error.h b/libs/libc/include/bits/error.h new file mode 100644 index 00000000..607695d8 --- /dev/null +++ b/libs/libc/include/bits/error.h @@ -0,0 +1,26 @@ +#ifndef _BITS_ERROR_H +#define _BITS_ERROR_H + +#include + +#define _RETURN_WITH_ERRNO(rc, type) \ + do { \ + if (rc < 0) \ + { \ + errno = (int)rc; \ + return -1; \ + } \ + return (type)rc; \ + } while (0) + +#define _RETURN_WITH_MEMORY_ERRNO(rc, type) \ + do { \ + if ((unsigned long int)rc > 0xffffffffffffff00) \ + { \ + errno = (int)((rc)&0xff); \ + return (type)-1; \ + } \ + return (type)rc; \ + } while (0) + +#endif \ No newline at end of file diff --git a/libs/libc/include/bits/macros.h b/libs/libc/include/bits/macros.h index 3bc212ec..16ede7b4 100644 --- a/libs/libc/include/bits/macros.h +++ b/libs/libc/include/bits/macros.h @@ -1,5 +1,5 @@ -#ifndef __BITS_MACROS_H -#define __BITS_MACROS_H +#ifndef _BITS_MACROS_H +#define _BITS_MACROS_H #define noreturn __attribute__((noreturn)) #define align(n) __attribute__((aligned(n))) diff --git a/libs/libc/include/errno.h b/libs/libc/include/errno.h index e69de29b..1caae45e 100644 --- a/libs/libc/include/errno.h +++ b/libs/libc/include/errno.h @@ -0,0 +1,10 @@ +#ifndef _ERRNO_H +#define _ERRNO_H + +extern int errno; + +#define EPERM 1 +#define ENOMEM 12 +#define EINVAL 22 + +#endif \ No newline at end of file diff --git a/libs/libc/include/sys/mman.h b/libs/libc/include/sys/mman.h new file mode 100644 index 00000000..3843a85d --- /dev/null +++ b/libs/libc/include/sys/mman.h @@ -0,0 +1,22 @@ +#ifndef _SYS_MMAN_H +#define _SYS_MMAN_H + +#include + +typedef unsigned long off_t; + +#define MAP_FAILED (void*)-1 + +#ifdef __cplusplus +extern "C" +{ +#endif + + void* mmap(void*, size_t, int, int, int, off_t); + int munmap(void* addr, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/libs/libc/src/bits/bindings.c b/libs/libc/src/bits/bindings.c index f8601d34..75b85898 100644 --- a/libs/libc/src/bits/bindings.c +++ b/libs/libc/src/bits/bindings.c @@ -1,6 +1,5 @@ #include -#include -#include +#include int liballoc_lock() { @@ -14,14 +13,12 @@ int liballoc_unlock() void* liballoc_alloc(size_t size) { - unsigned long int result = (unsigned long int)syscall(SYS_mmap, NULL, size * 4096, 1); + void* result = mmap(NULL, size * 4096, 0, 1, 0, 0); + if (result == MAP_FAILED) return 0; return (void*)result; } int liballoc_free(void* address, size_t size) { - int result = (int)syscall(SYS_munmap, address, size * 4096); - if (result < 0) return 1; - else - return 0; + return munmap(address, size * 4096); } \ No newline at end of file diff --git a/libs/libc/src/errno.cpp b/libs/libc/src/errno.cpp new file mode 100644 index 00000000..434ba1ab --- /dev/null +++ b/libs/libc/src/errno.cpp @@ -0,0 +1,3 @@ +#include + +int errno; \ No newline at end of file diff --git a/libs/libc/src/luna.cpp b/libs/libc/src/luna.cpp index abef73a9..eee9f2ae 100644 --- a/libs/libc/src/luna.cpp +++ b/libs/libc/src/luna.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -20,7 +21,6 @@ extern "C" noreturn void __luna_abort(const char* message) { syscall(SYS_write, message, strlen(message)); - syscall(SYS_exit); - __builtin_unreachable(); + abort(); } } \ No newline at end of file diff --git a/libs/libc/src/stdio.cpp b/libs/libc/src/stdio.cpp index d2da8940..eecf7621 100644 --- a/libs/libc/src/stdio.cpp +++ b/libs/libc/src/stdio.cpp @@ -50,6 +50,7 @@ extern "C" int puts(const char* s) { long nwritten = syscall(SYS_write, s, strlen(s)); + if (nwritten < 0) return -1; nwritten += syscall(SYS_write, "\n", 1); return (int)nwritten; } diff --git a/libs/libc/src/sys/mman.cpp b/libs/libc/src/sys/mman.cpp new file mode 100644 index 00000000..7b2a747f --- /dev/null +++ b/libs/libc/src/sys/mman.cpp @@ -0,0 +1,17 @@ +#include +#include +#include + +extern "C" +{ + // FIXME: Implement a POSIX-compliant mmap. + void* mmap(void* addr, size_t len, int, int flags, int, off_t) + { + return (void*)syscall(SYS_mmap, addr, len, flags); + } + + int munmap(void* addr, size_t len) + { + return (int)syscall(SYS_munmap, addr, len); + } +} \ No newline at end of file diff --git a/libs/libc/src/unistd.cpp b/libs/libc/src/unistd.cpp index 2e3e6593..25ef02cb 100644 --- a/libs/libc/src/unistd.cpp +++ b/libs/libc/src/unistd.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -62,7 +63,8 @@ extern "C" default: result = -1; break; } va_end(ap); - return result; + if (number == SYS_mmap) { _RETURN_WITH_MEMORY_ERRNO(result, long int); } + else { _RETURN_WITH_ERRNO(result, long); } } unsigned int sleep(unsigned int seconds)