Browse Source

feat(syscall): add clock_gettime64, getuid and prctl

greatbridf 1 year ago
parent
commit
696aaa567c

+ 2 - 2
gblibc/include/stdint.h

@@ -21,7 +21,7 @@ typedef __UINT64_TYPE__ uint64_t;
 typedef __SIZE_TYPE__ size_t;
 typedef int32_t ssize_t;
 
-typedef size_t time_t;
-typedef ssize_t time_diff_t;
+typedef uint64_t time_t;
+typedef int64_t time_diff_t;
 
 #endif

+ 17 - 0
gblibc/include/sys/prctl.h

@@ -0,0 +1,17 @@
+#ifndef __GBLIBC_SYS_PRCTL_H
+#define __GBLIBC_SYS_PRCTL_H
+
+#include <sys/types.h>
+
+#define PR_SET_NAME 15
+#define PR_GET_NAME 16
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 24 - 0
gblibc/include/time.h

@@ -0,0 +1,24 @@
+#ifndef __GBLIBC_TIME_H_
+#define __GBLIBC_TIME_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CLOCK_REALTIME 0
+
+typedef int clockid_t;
+
+struct timespec {
+    time_t tv_sec;
+    long tv_nsec;
+    int : 32; // padding
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 1 - 1
include/kernel/hw/timer.h

@@ -10,7 +10,7 @@ void init_pit(void);
 
 void inc_tick(void);
 
-time_t current_ticks(void);
+size_t current_ticks(void);
 
 #ifdef __cplusplus
 }

+ 5 - 2
include/kernel/process.hpp

@@ -72,15 +72,18 @@ public:
     int* __user set_child_tid {};
     int* __user clear_child_tid {};
 
-    explicit inline thread(pid_t owner)
+    types::string<> name {};
+
+    explicit inline thread(types::string<> name, pid_t owner)
         : owner { owner }
         , attr { .system = 1, .ready = 1, .wait = 0, }
+        , name { name }
     {
         alloc_kstack();
     }
 
     inline thread(const thread& val, pid_t owner)
-        : owner { owner } , attr { val.attr }
+        : owner { owner }, attr { val.attr }, name { val.name }
     {
         alloc_kstack();
     }

+ 2 - 2
src/kernel/hw/timer.c

@@ -1,7 +1,7 @@
 #include <asm/port_io.h>
 #include <kernel/hw/timer.h>
 
-static time_t _current_ticks = 0;
+static size_t _current_ticks = 0;
 
 SECTION(".text.kinit")
 void init_pit(void)
@@ -20,7 +20,7 @@ void inc_tick(void)
     ++_current_ticks;
 }
 
-time_t current_ticks(void)
+size_t current_ticks(void)
 {
     return _current_ticks;
 }

+ 3 - 2
src/kernel/process.cpp

@@ -246,7 +246,8 @@ void NORETURN _kernel_init(void)
     assert(proc.pid == 2);
 
     // create thread
-    auto [ iter_thd, inserted] = proc.thds.emplace(proc.pid);
+    auto [ iter_thd, inserted] =
+        proc.thds.emplace("[kernel thread daemon]", proc.pid);
     assert(inserted);
     auto& thd = *iter_thd;
 
@@ -360,7 +361,7 @@ void NORETURN init_scheduler(void)
     auto& init = procs->emplace(0);
     assert(init.pid == 1);
 
-    auto [ iter_thd, inserted ] = init.thds.emplace(init.pid);
+    auto [ iter_thd, inserted ] = init.thds.emplace("[kernel init]", init.pid);
     assert(inserted);
     auto& thd = *iter_thd;
 

+ 60 - 2
src/kernel/syscall.cpp

@@ -2,6 +2,8 @@
 #include <asm/sys.h>
 #include <assert.h>
 #include <bits/ioctl.h>
+#include <sys/prctl.h>
+#include <time.h>
 #include <kernel/user/thread_local.hpp>
 #include <kernel/errno.h>
 #include <kernel/interrupt.h>
@@ -12,6 +14,7 @@
 #include <kernel/syscall.hpp>
 #include <kernel/tty.hpp>
 #include <kernel/vfs.hpp>
+#include <kernel/hw/timer.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>
@@ -30,7 +33,7 @@
 #define SYSCALL_ARG5(type, name) type name = (type)((data)->s_regs.edi)
 #define SYSCALL_ARG6(type, name) type name = (type)((data)->s_regs.ebp)
 
-#define SYSCALL_HANDLERS_SIZE (385)
+#define SYSCALL_HANDLERS_SIZE (404)
 syscall_handler syscall_handlers[SYSCALL_HANDLERS_SIZE];
 
 extern "C" void _syscall_stub_fork_return(void);
@@ -521,11 +524,63 @@ ssize_t _syscall_writev(interrupt_stack* data)
     }
 }
 
+int _syscall_prctl(interrupt_stack* data)
+{
+    SYSCALL_ARG1(int, option);
+
+    switch (option) {
+    case PR_SET_NAME: {
+        // TODO: copy_from_user or check privilege
+        SYSCALL_ARG2(const char* __user, name);
+        current_thread->name.assign(name, 15);
+        break;
+    }
+    case PR_GET_NAME: {
+        SYSCALL_ARG2(char* __user, name);
+        // TODO: copy_to_user
+        strncpy(name, current_thread->name.c_str(), 16);
+        name[15] = 0;
+        break;
+    }
+    default:
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+int _syscall_clock_gettime64(interrupt_stack* data)
+{
+    SYSCALL_ARG1(clockid_t, clk_id);
+    SYSCALL_ARG2(timespec* __user, tp);
+
+    // TODO: check privilege of tp
+    if (clk_id != CLOCK_REALTIME || !tp)
+        return -EINVAL;
+
+    tp->tv_sec = 10 + current_ticks();
+    tp->tv_nsec = 0;
+
+    return 0;
+}
+
+int _syscall_getuid(interrupt_stack*)
+{
+    return 0; // all user is root for now
+}
+
 extern "C" void syscall_entry(interrupt_stack* data)
 {
     int syscall_no = SYSCALL_NO;
-    if (syscall_no >= SYSCALL_HANDLERS_SIZE)
+
+    if (syscall_no >= SYSCALL_HANDLERS_SIZE
+        || !syscall_handlers[syscall_no]) {
+        char buf[64];
+        snprintf(buf, 64,
+            "[kernel] syscall %x not implemented\n", syscall_no);
+        console->print(buf);
         kill_current(-1);
+    }
 
     int ret = syscall_handlers[syscall_no](data);
 
@@ -559,9 +614,12 @@ void init_syscall(void)
     syscall_handlers[0x84] = _syscall_getdents;
     syscall_handlers[0x92] = _syscall_writev;
     syscall_handlers[0x93] = _syscall_getsid;
+    syscall_handlers[0xac] = _syscall_prctl;
     syscall_handlers[0xb7] = _syscall_getcwd;
+    syscall_handlers[0xc7] = _syscall_getuid;
     syscall_handlers[0xf3] = _syscall_set_thread_area;
     syscall_handlers[0xfc] = _syscall_exit; // we implement exit_group as exit for now
     syscall_handlers[0x102] = _syscall_set_tid_address;
+    syscall_handlers[0x193] = _syscall_clock_gettime64;
     // syscall_handlers[35] = _syscall_sleep;
 }

+ 3 - 0
src/types/elf.cpp

@@ -179,5 +179,8 @@ int types::elf::elf32_load(types::elf::elf32_load_data* d)
     // push argc
     _user_push(sp, args.size());
 
+    // rename current thread
+    current_thread->name = ent_exec->name;
+
     return GB_OK;
 }