From d833e04f41440e0f0290bd5d567186beec6e9887 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 4 Jun 2015 18:17:39 +0100 Subject: [PATCH] break: zero space on allocation rather than doing it all on exec Allows the fast fork() handling to work correctly, and fixes the behaviour of a negative sbrk, followed by a positive one failing to clear the space. Tidy up the types involved. --- Kernel/include/kernel.h | 2 +- Kernel/syscall_exec16.c | 6 +++--- Kernel/syscall_proc.c | 26 +++++++++++++++++--------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/Kernel/include/kernel.h b/Kernel/include/kernel.h index 4220b587..d3b1d5bc 100644 --- a/Kernel/include/kernel.h +++ b/Kernel/include/kernel.h @@ -369,7 +369,7 @@ typedef struct u_data { uint16_t u_page2; /* Process page data (equal to u_ptab->p_page2) */ bool u_insys; /* True if in kernel */ uint8_t u_callno; /* sys call being executed. */ - void * u_syscall_sp; /* Stores SP when process makes system call */ + uaddr_t u_syscall_sp; /* Stores SP when process makes system call */ susize_t u_retval; /* Return value from sys call */ int16_t u_error; /* Last error number */ void * u_sp; /* Stores SP when process is switchped */ diff --git a/Kernel/syscall_exec16.c b/Kernel/syscall_exec16.c index 6575c154..cdb046ce 100644 --- a/Kernel/syscall_exec16.c +++ b/Kernel/syscall_exec16.c @@ -194,9 +194,9 @@ arg_t _execve(void) progptr += bin_size; } - /* Should be smarter on the uzero: bank align the clearance */ - // zero all remaining process memory above the last block loaded. - uzero((uint8_t *)progptr, top - progptr); + /* Wipe the memory in the BSS. We don't wipe the memory above + that on 8bit boxes, but defer it to brk/sbrk() */ + uzero((uint8_t *)progptr, progptr + bss); udata.u_break = (int) progptr + bss; // Set initial break for program diff --git a/Kernel/syscall_proc.c b/Kernel/syscall_proc.c index 307a59e6..418fa1ac 100644 --- a/Kernel/syscall_proc.c +++ b/Kernel/syscall_proc.c @@ -213,21 +213,29 @@ arg_t _times(void) brk (addr) Function 30 char *addr; ********************************************/ -#define addr (char *)udata.u_argn +#define addr (uaddr_t)udata.u_argn arg_t _brk(void) { - /* FIXME: when we start building binaries with the stack embedded in them - they will need a different test.. */ - /* Don't allow break to be set past user's stack pointer */ - /*** St. Nitschke allow min. of 512 bytes for Stack ***/ - if (addr >= (char *) brk_limit()) { + /* Don't allow break to be set outside of the range the platform + permits. For most platforms this is within 512 bytes of the + stack pointer + + FIXME: if we get more complex mapping rule types then we may + need to make this something like if (brk_valid(addr)) so we + can keep it portable */ + + if (addr >= brk_limit()) { kprintf("%d: out of memory\n", udata.u_ptab->p_pid); udata.u_error = ENOMEM; - return (-1); + return -1; } - udata.u_break = (uaddr_t) addr; - return (0); + /* If we have done a break that gives us more room we must zero + the extra as we no longer guarantee it is clear already */ + if (addr > udata.u_break) + uzero(udata.u_break, addr - udata.u_break); + udata.u_break = addr; + return 0; } #undef addr -- 2.34.1