From f5f3e51c9e3e1fdd7284f86ade2c3379f1a864c2 Mon Sep 17 00:00:00 2001
From: sambarr <s3-barr@>
Date: Thu, 13 Jul 2023 14:42:20 +0100
Subject: [PATCH] setup stack and started syscalls

---
 src/threads/thread.c   |   2 +
 src/userprog/process.c | 134 +++++++++++++++++++++++++++++++++++++++--
 src/userprog/syscall.c |  36 ++++++++++-
 3 files changed, 165 insertions(+), 7 deletions(-)

diff --git a/src/threads/thread.c b/src/threads/thread.c
index 052302f..1551f61 100644
--- a/src/threads/thread.c
+++ b/src/threads/thread.c
@@ -188,7 +188,9 @@ thread_create (const char *name, int priority,
     return TID_ERROR;
 
   /* Initialize thread. */
+  //printf("Starting init_thread\n");
   init_thread (t, name, priority);
+  //printf("Finished init_thread\n");
   tid = t->tid = allocate_tid ();
 
   /* Stack frame for kernel_thread(). */
diff --git a/src/userprog/process.c b/src/userprog/process.c
index d51339a..a4fbbee 100644
--- a/src/userprog/process.c
+++ b/src/userprog/process.c
@@ -29,6 +29,8 @@ tid_t
 process_execute (const char *file_name) 
 {
   char *fn_copy;
+  char *process_name;
+  char *save_ptr;
   tid_t tid;
 
   /* Make a copy of FILE_NAME.
@@ -38,9 +40,13 @@ process_execute (const char *file_name)
     return TID_ERROR;
   strlcpy (fn_copy, file_name, PGSIZE);
 
-  /* Create a new thread to execute FILE_NAME. */
-  tid = thread_create (file_name, PRI_DEFAULT, start_process, fn_copy);
+  // Extract process name from file
+  process_name = fn_copy + strlen(fn_copy)+1;
+  strlcpy(process_name, file_name, strlen(file_name)+1);
+  process_name = strtok_r(process_name, " ", &save_ptr);
 
+  /* Create a new thread to execute FILE_NAME. */
+  tid = thread_create (process_name, PRI_DEFAULT, start_process, fn_copy);
   if (tid == TID_ERROR)
     palloc_free_page (fn_copy); 
   return tid;
@@ -61,6 +67,7 @@ start_process (void *file_name_)
   if_.cs = SEL_UCSEG;
   if_.eflags = FLAG_IF | FLAG_MBS;
 
+  printf("Starting Load\n");
   success = load (file_name, &if_.eip, &if_.esp);
   
   /* If load failed, quit. */
@@ -103,6 +110,8 @@ process_exit (void)
   struct thread *cur = thread_current ();
   uint32_t *pd;
 
+  printf("%s:exit_code(%d)\n",cur->name);
+
   /* Destroy the current process's page directory and switch back
      to the kernel-only page directory. */
   pd = cur->pagedir;
@@ -200,7 +209,7 @@ struct Elf32_Phdr
 #define PF_W 2          /* Writable. */
 #define PF_R 4          /* Readable. */
 
-static bool setup_stack (void **esp);
+static bool setup_stack (void **esp, char *file_name);
 static bool validate_segment (const struct Elf32_Phdr *, struct file *);
 static bool load_segment (struct file *file, off_t ofs, uint8_t *upage,
                           uint32_t read_bytes, uint32_t zero_bytes,
@@ -227,7 +236,14 @@ load (const char *file_name, void (**eip) (void), void **esp)
   process_activate ();
 
   /* Open executable file. */
-  file = filesys_open (file_name);
+  char * fn_cp = malloc(strlen(file_name)+1);
+  strlcpy(fn_cp, file_name, strlen(file_name)+1);
+  char * save_ptr;
+  fn_cp = strtok_r(fn_cp," ", &save_ptr);
+
+  printf("Looking for file: %s\n",fn_cp);
+  file = filesys_open (fn_cp);
+  free(fn_cp);
 
   if (file == NULL) 
     {
@@ -308,7 +324,7 @@ load (const char *file_name, void (**eip) (void), void **esp)
     }
 
   /* Set up stack. */
-  if (!setup_stack (esp))
+  if (!setup_stack (esp, file_name))
     goto done;
 
   /* Start address. */
@@ -430,14 +446,51 @@ load_segment (struct file *file, off_t ofs, uint8_t *upage,
   return true;
 }
 
+// Used in setupstack to reverse tokens
+void reverse(char* begin, char* end)
+{
+    char temp;
+    while (begin < end) {
+        temp = *begin;
+        *begin++ = *end;
+        *end-- = temp;
+    }
+}
+ 
+// Function to reverse words*/
+void reverseWords(char* s)
+{
+    char* word_begin = s;
+ 
+    // Word boundary
+    char* temp = s;
+ 
+    // Reversing individual words as
+    // explained in the first step
+    while (*temp) {
+        temp++;
+        if (*temp == '\0') {
+            reverse(word_begin, temp - 1);
+        }
+        else if (*temp == ' ') {
+            reverse(word_begin, temp - 1);
+            word_begin = temp + 1;
+        }
+    }
+ 
+    // Reverse the entire string
+    reverse(s, temp - 1);
+}
+
 /* Create a minimal stack by mapping a zeroed page at the top of
    user virtual memory. */
 static bool
-setup_stack (void **esp) 
+setup_stack (void **esp, char *file_name) 
 {
   uint8_t *kpage;
   bool success = false;
 
+  printf("Setting up stack\n");
   kpage = palloc_get_page (PAL_USER | PAL_ZERO);
   if (kpage != NULL) 
     {
@@ -447,6 +500,75 @@ setup_stack (void **esp)
       } else
         palloc_free_page (kpage);
     }
+
+  char *token;
+  char *save_ptr;
+
+  // Initial size of 2, will be incremented as needed
+  int argv_size = 2;
+  int argc = 0;
+  char ** argv = malloc(argv_size * sizeof(char *));
+
+  // Convert char* to char array
+  char str[100];
+  for (int j=0; j<strlen(file_name)+1; j++)
+  {
+    str[j] = file_name[j];
+  }
+
+  // Reverse the filename such that arguments are first
+  reverseWords(str);
+  char *rev;
+  rev=str;
+
+  for (token = strtok_r(rev, " ", &save_ptr); token!=NULL;
+      token = strtok_r(NULL, " ", &save_ptr))
+  {
+    *esp -= strlen(token) + 1;
+    argv[argc] = *esp;
+    argc++;
+
+    if (argc >= 64)
+    {
+      free(argv);
+      return false;
+    }
+
+    if (argc >= argv_size)
+    {
+      argv_size *= 2;
+      argv = realloc(argv, argv_size* sizeof(char*));
+    }
+    memcpy(*esp,token,strlen(token)+1);
+  
+    //hex_dump(PHYS_BASE, *esp, PHYS_BASE-(*esp),true);
+  }
+
+  argv[argc] = 0;
+
+  // Load
+  int i = 0;
+  for (i=argc; i>=0; i--)
+  {
+    *esp -= sizeof(char*);
+    memcpy(*esp, &argv[i], sizeof(char*));
+  }
+
+  //Push argv address to stack
+  token = *esp;
+  *esp-=sizeof(char**);
+  memcpy(*esp,&token,sizeof(char**));
+
+  // Push argc to stack
+  *esp -= sizeof(int);
+  memcpy(*esp, &argc, sizeof(int));
+
+  // Push NULL Pointer
+  *esp -= sizeof(void*);
+  memcpy(*esp, &argv[argc], sizeof(void*));
+  free(argv);
+
+  hex_dump(PHYS_BASE, *esp, PHYS_BASE-(*esp),true);
   return success;
 }
 
diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c
index 0463515..08e82c9 100644
--- a/src/userprog/syscall.c
+++ b/src/userprog/syscall.c
@@ -3,8 +3,11 @@
 #include <syscall-nr.h>
 #include "threads/interrupt.h"
 #include "threads/thread.h"
+#include "devices/shutdown.h"
 
 static void syscall_handler (struct intr_frame *);
+void syscall_exit(int status);
+void syscall_halt(void);
 
 void
 syscall_init (void) 
@@ -14,8 +17,39 @@ syscall_init (void)
 
 
 static void
-syscall_handler (struct intr_frame *f UNUSED)
+syscall_handler (struct intr_frame *f)
 {
   printf ("system call!\n");
+  int sys_code = *(int*)f->esp;
+
+  printf("System call number: %d\n", sys_code);
+
+  switch(sys_code) {
+
+    case SYS_EXIT:
+      printf("Running SYS_EXIT\n");
+      //syscall_exit();
+      break;
+
+    case SYS_HALT:
+      printf("Running SYS_HALT\n");
+      syscall_halt();
+      break;
+
+    default:
+      printf("Unknown Syscall number\n");
+      break;
+  }
+
   thread_exit ();
 }
+
+
+/* System Call Implementations*/
+
+void syscall_exit(int status);
+
+void syscall_halt()
+{
+  shutdown_power_off();
+}
-- 
GitLab