Update stack initialization code to handle all possible overflows and implement a user program to test this
This commit is contained in:
@@ -28,6 +28,10 @@
|
||||
(for the purposes of alignment). */
|
||||
#define WORD_SIZE 4
|
||||
|
||||
/* Defines non-negative integer division wherein the result is always rounded
|
||||
up. */
|
||||
#define DIV_CEIL(x, y) ((x + (y - 1)) / y)
|
||||
|
||||
/* Keeps track of the position of pointers to user program arguments
|
||||
within a linked list. */
|
||||
struct arg_elem
|
||||
@@ -222,13 +226,19 @@ process_init_stack (char *cmd_saveptr, void **esp, char *file_name)
|
||||
+ return_addr_size;
|
||||
|
||||
/* If pushing the rest of the data required for the stack would cause
|
||||
overflow, allocate an extra page that is contiguous within the
|
||||
virtual address space (below the current address range). */
|
||||
if (PHYS_BASE - *esp + remaining_size > PGSIZE)
|
||||
overflow, allocate as many extra pages as needed to the user process
|
||||
contiguously in the virtual address space below the initial page. */
|
||||
int overflow_bytes = (PHYS_BASE - *esp) + remaining_size - PGSIZE;
|
||||
if (overflow_bytes > 0)
|
||||
{
|
||||
uint8_t *kpage = palloc_get_page (PAL_USER | PAL_ZERO);
|
||||
if (!install_page (((uint8_t *) PHYS_BASE) - PGSIZE * 2, kpage, true))
|
||||
return false;
|
||||
int pages_needed = DIV_CEIL (overflow_bytes, PGSIZE);
|
||||
for (int i = 1; i < pages_needed + 1; i++)
|
||||
{
|
||||
uint8_t *kpage = palloc_get_page (PAL_USER | PAL_ZERO);
|
||||
if (!install_page (((uint8_t *) PHYS_BASE) - PGSIZE * (i + 1),
|
||||
kpage, true))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Align stack pointer to word size before pushing argv elements for
|
||||
|
||||
Reference in New Issue
Block a user