summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordzwdz2022-07-08 21:11:10 +0200
committerdzwdz2022-07-08 21:11:10 +0200
commit1d20df331cb4540bac157ac779d035d189ef669c (patch)
treefa8d574ec165bbeea9dc3062a1e20f5fd937f5b0
parent2f520b5e0101a3cb9404371e1152affc934e40b2 (diff)
kernel/syscalls: fix the SYSCALL_RETURN macro for returning pointers
-rw-r--r--Makefile3
-rw-r--r--src/kernel/syscalls.c15
2 files changed, 9 insertions, 9 deletions
diff --git a/Makefile b/Makefile
index bf0f1f6..98397ca 100644
--- a/Makefile
+++ b/Makefile
@@ -6,6 +6,7 @@ CHECK = sparse
CFLAGS += -g -std=gnu99 -ffreestanding -O2 -Wall -Wextra -Wold-style-definition -Werror=implicit-function-declaration -ftrack-macro-expansion=0
CFLAGS += -mgeneral-regs-only
CFLAGS += -Isrc/
+SPARSEFLAGS = -Wno-non-pointer-null
LFLAGS = -ffreestanding -O2 -nostdlib -lgcc
QFLAGS = -no-reboot
ifndef QEMU_DISPLAY
@@ -45,7 +46,7 @@ lint:
@tools/linter/main.rb
check: $(shell find src/kernel/ -type f -name *.c)
- @echo $^ | xargs -n 1 sparse $(CFLAGS)
+ @echo $^ | xargs -n 1 sparse $(CFLAGS) $(SPARSEFLAGS)
clean:
rm -rv out/
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index e639d1f..cfd895e 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -11,8 +11,10 @@
#include <stdint.h>
#define SYSCALL_RETURN(val) do { \
+ uint32_t ret = (uint32_t)val; \
assert(process_current->state == PS_RUNNING); \
- return regs_savereturn(&process_current->regs, val); \
+ regs_savereturn(&process_current->regs, ret); \
+ return 0; \
} while (0)
_Noreturn void _syscall_exit(int ret) {
@@ -29,7 +31,7 @@ int _syscall_await(void) {
{
if (iter->noreap) continue;
has_children = true;
- if (iter->state == PS_DEAD) // TODO this path crashes
+ if (iter->state == PS_DEAD) // TODO this path used to crash, still untested
SYSCALL_RETURN(process_try2collect(iter));
}
@@ -272,7 +274,8 @@ void __user *_syscall_memflag(void __user *addr, size_t len, int flags) {
if (flags & MEMFLAG_FINDFREE) {
addr = pagedir_findfree(pages, addr, len);
- if (!(flags & MEMFLAG_PRESENT)) goto ret;
+ if (!(flags & MEMFLAG_PRESENT))
+ SYSCALL_RETURN((uintptr_t)addr);
}
@@ -296,11 +299,7 @@ void __user *_syscall_memflag(void __user *addr, size_t len, int flags) {
pagedir_map(pages, iter, phys, true, true);
}
}
-
-ret: // the macro is too stupid to handle returning pointers
- assert(process_current->state == PS_RUNNING); // TODO move to regs_savereturn
- regs_savereturn(&process_current->regs, (uintptr_t)addr);
- return addr;
+ SYSCALL_RETURN((uintptr_t)addr);
}
handle_t _syscall_pipe(int flags) {