syscall log: support for selective syscall tracing

This commit is contained in:
2025-12-29 14:25:12 +01:00
committed by Matheus
parent 91e2430d91
commit 963d29fc90
9 changed files with 155 additions and 0 deletions
+28
View File
@@ -1,3 +1,4 @@
#include <arch/cpu.h>
#include <kernel/syscalls.h>
#include <arch/msr.h>
#include <errno.h>
@@ -6,6 +7,11 @@
#define ARCH_CTL_SET_FSBASE 1
#define ARCH_CTL_GET_GSBASE 2
#define ARCH_CTL_GET_FSBASE 3
#define ARCH_CTL_SET_SYSTRACE 4
#define ARCH_CTL_SYSTRACE_OFF 0
#define ARCH_CTL_SYSTRACE_SELF 1
#define ARCH_CTL_SYSTRACE_ALL 2
static inline int copy_u64_to_user(void *ptr, uint64_t v) {
return usercopy_touser(ptr, &v, sizeof(v));
@@ -36,6 +42,28 @@ syscallret_t syscall_archctl(context_t *context, int func, void *arg) {
case ARCH_CTL_GET_FSBASE:
ret.errno = copy_u64_to_user(arg, rdmsr(MSR_FSBASE));
break;
case ARCH_CTL_SET_SYSTRACE:
#ifdef SYSCALL_LOGGING
switch ((uint64_t)arg) {
case ARCH_CTL_SYSTRACE_OFF:
current_thread()->proc->flags &= ~(PROC_FLAG_SYSTRACE | PROC_FLAG_SYSTRACE_SELF);
break;
case ARCH_CTL_SYSTRACE_SELF:
current_thread()->proc->flags |= PROC_FLAG_SYSTRACE | PROC_FLAG_SYSTRACE_SELF;
break;
case ARCH_CTL_SYSTRACE_ALL:
current_thread()->proc->flags |= PROC_FLAG_SYSTRACE;
current_thread()->proc->flags &= ~PROC_FLAG_SYSTRACE_SELF;
break;
default:
ret.errno = EINVAL;
break;
}
#else
// signal that syscall logging is not supported
ret.errno = ENOTSUP;
#endif
break;
default:
ret.errno = EINVAL;
break;
+8
View File
@@ -5,6 +5,9 @@
#ifdef SYSCALL_LOGGING
void arch_interrupt_disable();
void arch_interrupt_enable();
#define SYSCALL_COUNT 99
#define LOGSTR(x) arch_e9_puts(x)
@@ -225,6 +228,9 @@ __attribute__((no_caller_saved_registers)) void arch_syscall_log(int syscall, ui
thread_t *thread = current_thread();
proc_t *proc = thread->proc;
if (!(proc->flags & PROC_FLAG_SYSTRACE))
return;
snprintf(argbuff, 768, syscall < SYSCALL_COUNT ? args[syscall] : "N/A", a1, a2, a3, a4, a5, a6);
snprintf(printbuff, 1024, "\e[92msyscall: pid %d tid %d: %s: %s (%lu cached pages, %lu free pages)\n\e[0m", proc->pid, thread->tid, syscall < SYSCALL_COUNT ? name[syscall] : "invalid syscall", argbuff, vmmcache_cachedpages, freepagecount);
@@ -242,6 +248,8 @@ __attribute__((no_caller_saved_registers)) void arch_syscall_log_return(uint64_t
thread_t *thread = current_thread();
proc_t *proc = thread->proc;
if (!(proc->flags & PROC_FLAG_SYSTRACE))
return;
snprintf(printbuff, 1024, "\e[94msyscall return: pid %d tid %d: %lu %s (%lu cached pages, %lu free pages)\n\e[0m", proc->pid, thread->tid, ret, strerror(errno), vmmcache_cachedpages, freepagecount);
arch_interrupt_disable();
+3
View File
@@ -16,6 +16,9 @@
#define PROC_STATE_NORMAL 0
#define PROC_STATE_ZOMBIE 1
#define PROC_FLAG_SYSTRACE (1 << 0)
#define PROC_FLAG_SYSTRACE_SELF (1 << 1)
typedef struct proc_t {
mutex_t mutex;
int refcount;
+3
View File
@@ -50,6 +50,9 @@ syscallret_t syscall_fork(context_t *ctx) {
nproc->root = proc_get_root();
nproc->cwd = proc_get_cwd();
nproc->threadlist = nthread;
if (proc->flags & PROC_FLAG_SYSTRACE && !(proc->flags & PROC_FLAG_SYSTRACE_SELF))
nproc->flags |= PROC_FLAG_SYSTRACE;
nthread->procnext = NULL;
ARCH_CONTEXT_THREADSAVE(nthread, ctx);