From fb0323c8cef5ff7307cb27103e818cdd61338d57 Mon Sep 17 00:00:00 2001 From: "Enrico Fraccaroli (Galfurian)" Date: Fri, 9 Jun 2023 15:36:03 -0400 Subject: [PATCH] Create a temporary solution to call a 6-arguments system call (specifically, mmap). --- libc/CMakeLists.txt | 1 + libc/inc/sys/mman.h | 23 +++++++++++++++ libc/inc/system/syscall_types.h | 51 +++++++++++++++++++++++++-------- libc/src/sys/mman.c | 14 +++++++++ mentos/src/mem/paging.c | 16 +++++++++++ mentos/src/system/syscall.c | 15 ++++++++-- 6 files changed, 105 insertions(+), 15 deletions(-) create mode 100644 libc/inc/sys/mman.h create mode 100644 libc/src/sys/mman.c diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt index 9e909e9..4034ce0 100644 --- a/libc/CMakeLists.txt +++ b/libc/CMakeLists.txt @@ -99,6 +99,7 @@ add_library( ${PROJECT_SOURCE_DIR}/src/sys/unistd.c ${PROJECT_SOURCE_DIR}/src/sys/errno.c ${PROJECT_SOURCE_DIR}/src/sys/utsname.c + ${PROJECT_SOURCE_DIR}/src/sys/mman.c ${PROJECT_SOURCE_DIR}/src/sys/ioctl.c ${PROJECT_SOURCE_DIR}/src/unistd/creat.c ${PROJECT_SOURCE_DIR}/src/unistd/getppid.c diff --git a/libc/inc/sys/mman.h b/libc/inc/sys/mman.h new file mode 100644 index 0000000..f03c962 --- /dev/null +++ b/libc/inc/sys/mman.h @@ -0,0 +1,23 @@ +/// @file mman.h +/// @author Enrico Fraccaroli (enry.frak@gmail.com) +/// @brief Functions for managing mappings in virtual address space. +/// @copyright (c) 2014-2023 This file is distributed under the MIT License. +/// See LICENSE.md for details. + +#pragma once + +#include "stddef.h" + +#ifndef __KERNEL__ + +void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); + +int munmap(void *addr, size_t length); + +#else + +void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); + +int sys_munmap(void *addr, size_t length); + +#endif diff --git a/libc/inc/system/syscall_types.h b/libc/inc/system/syscall_types.h index 6c29f8c..e576e71 100644 --- a/libc/inc/system/syscall_types.h +++ b/libc/inc/system/syscall_types.h @@ -207,6 +207,17 @@ return (type)(res); \ } while (0) +// Few things about what follows: +// +// 1. The symbol "=", is a a constraint modifier, and it means that the operand +// is write-only, meaning that the previous value is discarded and replaced +// by output data. +// +// 2. Using "0" here specifies that the input is read from a variable which also +// serves as an output, the 0-th output variable in this case. +// +// + /// @brief Heart of the code that calls a system call with 0 parameters. #define __inline_syscall0(res, name) \ __asm__ __volatile__("int $0x80" \ @@ -214,37 +225,37 @@ : "0"(__NR_##name)) /// @brief Heart of the code that calls a system call with 1 parameter. -#define __inline_syscall1(res, name, arg1) \ - __asm__ __volatile__("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ - : "=a"(res) \ - : "0"(__NR_##name), "ri"(arg1) \ +#define __inline_syscall1(res, name, arg1) \ + __asm__ __volatile__("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a"(res) \ + : "0"(__NR_##name), "ri"(arg1) \ : "memory"); /// @brief Heart of the code that calls a system call with 2 parameters. -#define __inline_syscall2(res, name, arg1, arg2) \ - __asm__ __volatile__("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ - : "=a"(res) \ - : "0"(__NR_##name), "ri"(arg1), "c"(arg2) \ +#define __inline_syscall2(res, name, arg1, arg2) \ + __asm__ __volatile__("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a"(res) \ + : "0"(__NR_##name), "ri"(arg1), "c"(arg2) \ : "memory"); /// @brief Heart of the code that calls a system call with 3 parameters. #define __inline_syscall3(res, name, arg1, arg2, arg3) \ - __asm__ __volatile__("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ + __asm__ __volatile__("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ : "=a"(res) \ : "0"(__NR_##name), "ri"(arg1), "c"(arg2), "d"(arg3) \ : "memory"); /// @brief Heart of the code that calls a system call with 4 parameters. #define __inline_syscall4(res, name, arg1, arg2, arg3, arg4) \ - __asm__ __volatile__("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ + __asm__ __volatile__("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ : "=a"(res) \ : "0"(__NR_##name), "ri"(arg1), "c"(arg2), "d"(arg3), "S"(arg4) \ : "memory"); /// @brief Heart of the code that calls a system call with 5 parameters. #define __inline_syscall5(res, name, arg1, arg2, arg3, arg4, arg5) \ - __asm__ __volatile__("push %%ebx ; movl %2,%%ebx ; movl %1,%%eax ; " \ - "int $0x80 ; pop %%ebx" \ + __asm__ __volatile__("push %%ebx; movl %2,%%ebx; movl %1,%%eax; " \ + "int $0x80; pop %%ebx" \ : "=a"(res) \ : "i"(__NR_##name), "ri"(arg1), "c"(arg2), "d"(arg3), "S"(arg4), "D"(arg5) \ : "memory"); @@ -302,3 +313,19 @@ __inline_syscall5(__res, name, arg1, arg2, arg3, arg4, arg5); \ __syscall_return(type, __res); \ } + +/// @brief System call with 5 parameters. +#define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5, type6, arg6) \ + type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \ + { \ + long __res; \ + unsigned args[6] = { 0 }; \ + args[0] = (unsigned)arg1; \ + args[1] = (unsigned)arg2; \ + args[2] = (unsigned)arg3; \ + args[3] = (unsigned)arg4; \ + args[4] = (unsigned)arg5; \ + args[5] = (unsigned)arg6; \ + __inline_syscall1(__res, name, args); \ + __syscall_return(type, __res); \ + } diff --git a/libc/src/sys/mman.c b/libc/src/sys/mman.c new file mode 100644 index 0000000..d4a53d5 --- /dev/null +++ b/libc/src/sys/mman.c @@ -0,0 +1,14 @@ +/// @file mman.c +/// @author Enrico Fraccaroli (enry.frak@gmail.com) +/// @brief Functions for managing mappings in virtual address space. +/// @copyright (c) 2014-2023 This file is distributed under the MIT License. +/// See LICENSE.md for details. + +#include "sys/mman.h" +#include "system/syscall_types.h" +#include "sys/unistd.h" +#include "sys/errno.h" + +_syscall6(void *, mmap, void *, addr, size_t, length, int, prot, int, flags, int, fd, off_t, offset) + +_syscall2(int, munmap, void *, addr, size_t, length) diff --git a/mentos/src/mem/paging.c b/mentos/src/mem/paging.c index a8a09a3..821dd4e 100644 --- a/mentos/src/mem/paging.c +++ b/mentos/src/mem/paging.c @@ -625,3 +625,19 @@ void destroy_process_image(mm_struct_t *mm) // Free the mm_struct. kmem_cache_free(mm); } + +void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) +{ + pr_warning("%p\n", addr); + pr_warning("%d\n", length); + pr_warning("%d\n", prot); + pr_warning("%d\n", flags); + pr_warning("%d\n", fd); + pr_warning("%d\n", offset); + return NULL; +} + +int sys_munmap(void *addr, size_t length) +{ + return 0; +} diff --git a/mentos/src/system/syscall.c b/mentos/src/system/syscall.c index ad32974..9e27ff7 100644 --- a/mentos/src/system/syscall.c +++ b/mentos/src/system/syscall.c @@ -4,7 +4,8 @@ /// See LICENSE.md for details. // Setup the logging for this file (do this before any other include). -#include "sys/kernel_levels.h" // Include kernel log levels. +#include "sys/kernel_levels.h" // Include kernel log levels. +#include "system/syscall_types.h" #define __DEBUG_HEADER__ "[SYSCLL]" ///< Change header. #define __DEBUG_LEVEL__ LOGLEVEL_NOTICE ///< Set log level. #include "io/debug.h" // Include debugging functions. @@ -21,6 +22,7 @@ #include "sys/errno.h" #include "sys/utsname.h" +#include "sys/mman.h" #include "sys/msg.h" #include "sys/sem.h" #include "sys/shm.h" @@ -129,7 +131,7 @@ void syscall_init() sys_call_table[__NR_swapon] = (SystemCall)sys_ni_syscall; sys_call_table[__NR_reboot] = (SystemCall)sys_reboot; sys_call_table[__NR_readdir] = (SystemCall)sys_ni_syscall; - sys_call_table[__NR_mmap] = (SystemCall)sys_ni_syscall; + sys_call_table[__NR_mmap] = (SystemCall)sys_mmap; sys_call_table[__NR_munmap] = (SystemCall)sys_ni_syscall; sys_call_table[__NR_truncate] = (SystemCall)sys_ni_syscall; sys_call_table[__NR_ftruncate] = (SystemCall)sys_ni_syscall; @@ -278,7 +280,14 @@ void syscall_handler(pt_regs *f) (sc_index == __NR_sigreturn)) { arg0 = (uintptr_t)f; } - ret = func(arg0, arg1, arg2, arg3, arg4); + if (sc_index == __NR_mmap) { + // Get the arguments. + unsigned *args = (unsigned *)arg0; + // Call the function. + ret = func(args[0], args[1], args[2], args[3], args[4], args[5]); + } else { + ret = func(arg0, arg1, arg2, arg3, arg4); + } } f->eax = ret;