summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
authordzwdz2021-08-11 15:57:21 +0000
committerdzwdz2021-08-11 15:57:21 +0000
commita32374156ea2cf129b413fa017d7e52e59570c04 (patch)
tree0d191308425e6bf376d539b4b77e9485b1cf8722 /src/kernel
parent0dbd5803e14d72b45ddae17e25bdd84308410f9a (diff)
read _syscall_debuglog arguments across page boundaries
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/syscalls.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index 47f8b2b..7234e10 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -23,15 +23,27 @@ int _syscall_fork() {
int _syscall_debuglog(const char *msg, size_t len) {
struct pagedir *pages = process_current->pages;
- void *phys = pagedir_virt2phys(pages, msg, true, false);
+ size_t remaining = len;
- // page overrun check
- if (((uintptr_t)msg & PAGE_MASK) + len > PAGE_SIZE)
- len = PAGE_SIZE - ((uintptr_t)msg & PAGE_MASK);
- if (((uintptr_t)msg & PAGE_MASK) + len > PAGE_SIZE)
- panic(); // just in case I made an off by 1 error
+ while (remaining > 0) {
+ /* note: While i'm pretty sure that this should always work, this
+ * was only tested in cases where the pages were consecutive both in
+ * virtual and physical memory, which might not always be the case.
+ * TODO test this */
+
+ void *phys = pagedir_virt2phys(pages, msg, true, false);
+ size_t partial = remaining;
+
+ // don't read past the page
+ if (((uintptr_t)msg & PAGE_MASK) + remaining > PAGE_SIZE)
+ partial = PAGE_SIZE - ((uintptr_t)msg & PAGE_MASK);
+
+ tty_write(phys, partial);
+
+ remaining -= partial;
+ msg += partial;
+ }
- tty_write(phys, len);
return len;
}