Skip to content
Snippets Groups Projects
Commit 7f930d2c authored by s2-fidan's avatar s2-fidan
Browse files

save

parent b35e7104
No related branches found
No related tags found
No related merge requests found
...@@ -31,8 +31,10 @@ tid_t ...@@ -31,8 +31,10 @@ tid_t
process_execute(const char *file_name) process_execute(const char *file_name)
{ {
char *file_copy; char *file_copy;
char *ptr;
tid_t tid; tid_t tid;
char *ptr = NULL;
int file_name_length = strlen(file_name) + 1;
char program[file_name_length];
/* Make a copy of command line. Otherwise there's a race between the caller and load(). */ /* Make a copy of command line. Otherwise there's a race between the caller and load(). */
file_copy = palloc_get_page(0); file_copy = palloc_get_page(0);
...@@ -40,8 +42,10 @@ process_execute(const char *file_name) ...@@ -40,8 +42,10 @@ process_execute(const char *file_name)
return TID_ERROR; return TID_ERROR;
strlcpy(file_copy, file_name, PGSIZE); strlcpy(file_copy, file_name, PGSIZE);
/* Extract file_name from command line. */ /* Parse first argument as program name */
file_name = strtok_r(file_name, " ", &ptr); strlcpy(program, file_name, file_name_length);
strtok_r(program, " ", &ptr);
printf("\nProgram name: %s\n\n", program) ;
/* Create a new thread to execute FILE_NAME. */ /* Create a new thread to execute FILE_NAME. */
tid = thread_create(file_name, PRI_DEFAULT, start_process, file_copy); tid = thread_create(file_name, PRI_DEFAULT, start_process, file_copy);
...@@ -61,7 +65,7 @@ start_process (void *file_name_) ...@@ -61,7 +65,7 @@ start_process (void *file_name_)
char *file_name = file_name_; char *file_name = file_name_;
struct intr_frame if_; struct intr_frame if_;
bool success; bool success;
char* temp[50]; char *parse[250];
char *token; char *token;
char *ptr; char *ptr;
int count = 0; int count = 0;
...@@ -69,8 +73,11 @@ start_process (void *file_name_) ...@@ -69,8 +73,11 @@ start_process (void *file_name_)
for (token = strtok_r(file_name, " ", &ptr); token != NULL; for (token = strtok_r(file_name, " ", &ptr); token != NULL;
token = strtok_r(NULL, " ", &ptr)) token = strtok_r(NULL, " ", &ptr))
{ {
temp[count++] = token; parse[count] = token;
count++;
printf("\nTokenized Argument: %s\n", parse[count - 1]);
} }
printf("\nNumber of tokenized Arguments : %d\n", count);
/* Initialize interrupt frame and load executable. */ /* Initialize interrupt frame and load executable. */
memset(&if_, 0, sizeof if_); memset(&if_, 0, sizeof if_);
...@@ -78,9 +85,9 @@ start_process (void *file_name_) ...@@ -78,9 +85,9 @@ start_process (void *file_name_)
if_.cs = SEL_UCSEG; if_.cs = SEL_UCSEG;
if_.eflags = FLAG_IF | FLAG_MBS; if_.eflags = FLAG_IF | FLAG_MBS;
success = load (file_name, &if_.eip, &if_.esp); success = load(parse[0], &if_.eip, &if_.esp);
argument_pushing(&temp, count, &if_.esp); argument_pushing(&parse, count, &if_.esp);
hex_dump(if_.esp, if_.esp, PHYS_BASE - if_.esp, true); hex_dump(if_.esp, if_.esp, PHYS_BASE - if_.esp, true);
...@@ -157,7 +164,7 @@ process_activate (void) ...@@ -157,7 +164,7 @@ process_activate (void)
interrupts. */ interrupts. */
tss_update(); tss_update();
} }
/* We load ELF binaries. The following definitions are taken /* We load ELF binaries. The following definitions are taken
from the ELF specification, [ELF1], more-or-less verbatim. */ from the ELF specification, [ELF1], more-or-less verbatim. */
...@@ -221,7 +228,7 @@ struct Elf32_Phdr ...@@ -221,7 +228,7 @@ struct Elf32_Phdr
#define PF_W 2 /* Writable. */ #define PF_W 2 /* Writable. */
#define PF_R 4 /* Readable. */ #define PF_R 4 /* Readable. */
static bool setup_stack (void **esp, char * cmdline); static bool setup_stack(void **esp);
static bool validate_segment(const struct Elf32_Phdr *, struct file *); static bool validate_segment(const struct Elf32_Phdr *, struct file *);
static bool load_segment(struct file *file, off_t ofs, uint8_t *upage, static bool load_segment(struct file *file, off_t ofs, uint8_t *upage,
uint32_t read_bytes, uint32_t zero_bytes, uint32_t read_bytes, uint32_t zero_bytes,
...@@ -257,13 +264,7 @@ load (const char *file_name, void (**eip) (void), void **esp) ...@@ -257,13 +264,7 @@ load (const char *file_name, void (**eip) (void), void **esp)
} }
/* Read and verify executable header. */ /* Read and verify executable header. */
if (file_read (file, &ehdr, sizeof ehdr) != sizeof ehdr if (file_read(file, &ehdr, sizeof ehdr) != sizeof ehdr || memcmp(ehdr.e_ident, "\177ELF\1\1\1", 7) || ehdr.e_type != 2 || ehdr.e_machine != 3 || ehdr.e_version != 1 || ehdr.e_phentsize != sizeof(struct Elf32_Phdr) || ehdr.e_phnum > 1024)
|| memcmp (ehdr.e_ident, "\177ELF\1\1\1", 7)
|| ehdr.e_type != 2
|| ehdr.e_machine != 3
|| ehdr.e_version != 1
|| ehdr.e_phentsize != sizeof (struct Elf32_Phdr)
|| ehdr.e_phnum > 1024)
{ {
printf("load: %s: error loading executable\n", file_name); printf("load: %s: error loading executable\n", file_name);
goto done; goto done;
...@@ -308,8 +309,7 @@ load (const char *file_name, void (**eip) (void), void **esp) ...@@ -308,8 +309,7 @@ load (const char *file_name, void (**eip) (void), void **esp)
/* Normal segment. /* Normal segment.
Read initial part from disk and zero the rest. */ Read initial part from disk and zero the rest. */
read_bytes = page_offset + phdr.p_filesz; read_bytes = page_offset + phdr.p_filesz;
zero_bytes = (ROUND_UP (page_offset + phdr.p_memsz, PGSIZE) zero_bytes = (ROUND_UP(page_offset + phdr.p_memsz, PGSIZE) - read_bytes);
- read_bytes);
} }
else else
{ {
...@@ -452,41 +452,57 @@ load_segment (struct file *file, off_t ofs, uint8_t *upage, ...@@ -452,41 +452,57 @@ load_segment (struct file *file, off_t ofs, uint8_t *upage,
} }
/* References: J,Choi(2014), pintos. Available from: https://github.com/wookayin/pintos [accessed on 23/11/22]*/ /* References: J,Choi(2014), pintos. Available from: https://github.com/wookayin/pintos [accessed on 23/11/22]*/
static void static void
argument_pushing (char** parse, int argc, void **esp) argument_pushing(char **parse, int count, void **esp)
{ {
/* Increment Counter */ int i, j;
int i; int length = 0; // Argument length
int len=0; int parse0_address; // First Argument's Adress
int argv_addr[argc]; int address[count]; // Argument adress
for (i = 0; i < argc; i++) {
len = strlen(parse[i]) + 1; /*Push arguments to stack one by one*/
*esp -= len; for (i = count - 1; i > -1; i--)
memcpy(*esp, parse[i], len); {
argv_addr[i] = (int) *esp; for (j = strlen(parse[i]); j > -1; j--)
{
*esp = *esp - 1;
**(char **)esp = parse[i][j];
length++; /*Count length of arguments we pushed*/
} }
/*Store address of argument*/
address[i] = *(unsigned int *)esp;
printf("\nAdress of %d 's argument: %d\n", i + 1, address[i]);
}
printf("\nNumber of arguments pushed onto stack: %d\n", length);
/* Word Allignment*/ /* Word Allignment*/
*esp = (int)*esp & 0xfffffffc; for (i = 0; i < 4 - (length % 4); i++)
{
*esp = *esp - 1;
**(uint8_t **)esp = 0;
}
/* Last null*/ /* Last argument needs to be NULL*/
*esp -= 4; *esp -= 4;
*(int*)*esp = 0; **(char ***)esp = 0;
/* Use argvs to set **esp */ /*Push argument adress - Use counter to set **esp */
for (i = argc - 1; i >= 0; i--) { for (i = count - 1; i >= 0; i--)
{
*esp -= 4; *esp -= 4;
*(int*)*esp = argv_addr[i]; **(char ***)esp = address[i];
} }
/* Set **argv*/ /* Set **argv*/
parse0_address = *(unsigned int *)esp;
*esp -= 4; *esp -= 4;
*(int*)*esp = (int)*esp + 4; **(char ***)esp = (char *)parse0_address;
/* Set argc*/ /* Set counter*/
*esp -= 4; *esp -= 4;
*(int*)*esp = argc; *(int *)*esp = count;
/* Set ret*/ /*Fake Adress - Set ret*/
*esp -= 4; *esp -= 4;
*(int *)*esp = 0; *(int *)*esp = 0;
} }
...@@ -503,77 +519,11 @@ setup_stack (void **esp) ...@@ -503,77 +519,11 @@ setup_stack (void **esp)
if (kpage != NULL) if (kpage != NULL)
{ {
success = install_page(((uint8_t *)PHYS_BASE) - PGSIZE, kpage, true); success = install_page(((uint8_t *)PHYS_BASE) - PGSIZE, kpage, true);
if (success) { if (success)
*esp = PHYS_BASE; *esp = PHYS_BASE;
} else
palloc_free_page (kpage);
}
char *token, *temp_ptr;
char * flname_cp = malloc(strlen(file_name)+1);
strlcpy (flname_cp, file_name, strlen(file_name)+1);
/* argc calculation*/
enum intr_level old_level = intr_disable();
int argc=1;
/* Is the last char a space? - Only one space in the end*/
bool is_lastchar_space=false;
for(int j=0;j!=strlen(file_name); j++){
if(file_name[j] == ' '){
if(!is_lastchar_space)
argc++;
is_lastchar_space=true;
}
else else
is_lastchar_space=false; palloc_free_page(kpage);
}
intr_set_level (old_level);
int *argv = calloc(argc,sizeof(int));
int i;
token = strtok_r (file_name, " ", &temp_ptr);
for (i=0; ; i++){
if(token){
*esp -= strlen(token) + 1;
memcpy(*esp,token,strlen(token) + 1);
argv[i]=*esp;
token = strtok_r (NULL, " ", &temp_ptr);
}else{
break;
}
}
/* Word alignment*/
*esp -= ((unsigned)*esp % WORD_SIZE);
/* Null ptr sentinel: null at argv[argc]*/
*esp-=sizeof(int);
/* Push address*/
for(i=argc-1;i>=0;i--)
{
*esp-=sizeof(int);
memcpy(*esp,&argv[i],sizeof(int));
} }
/* Push argv address*/
int tmp = *esp;
*esp-=sizeof(int);
memcpy(*esp,&tmp,sizeof(int));
/* Push argc*/
*esp-=sizeof(int);
memcpy(*esp,&argc,sizeof(int));
/* Return address*/
*esp-=sizeof(int);
memcpy(*esp,&argv[argc],sizeof(int));
free(flname_cp);
free(argv);
return success; return success;
} }
...@@ -593,8 +543,7 @@ install_page (void *upage, void *kpage, bool writable) ...@@ -593,8 +543,7 @@ install_page (void *upage, void *kpage, bool writable)
/* Verify that there's not already a page at that virtual /* Verify that there's not already a page at that virtual
address, then map our page there. */ address, then map our page there. */
return (pagedir_get_page (t->pagedir, upage) == NULL return (pagedir_get_page(t->pagedir, upage) == NULL && pagedir_set_page(t->pagedir, upage, kpage, writable));
&& pagedir_set_page (t->pagedir, upage, kpage, writable));
} }
//-------------------------------------------------------------------- //--------------------------------------------------------------------
...@@ -3,6 +3,10 @@ ...@@ -3,6 +3,10 @@
#include "threads/thread.h" #include "threads/thread.h"
typedef int pit_t;
#define PID_ERROR ((pid_t)-1)
#define PID_INITIALIZING ((pid_t) -2)
tid_t process_execute (const char *file_name); tid_t process_execute (const char *file_name);
int process_wait (tid_t); int process_wait (tid_t);
void process_exit (void); void process_exit (void);
......
#include "userprog/syscall.h" #include "userprog/syscall.h"
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <syscall-nr.h> #include <syscall-nr.h>
#include "threads/interrupt.h" #include "threads/interrupt.h"
...@@ -6,16 +7,149 @@ ...@@ -6,16 +7,149 @@
static void syscall_handler (struct intr_frame *); static void syscall_handler (struct intr_frame *);
/*System call initializer*/
void void
syscall_init (void) syscall_init (void)
{ {
intr_register_int (0x30, 3, INTR_ON, syscall_handler, "syscall"); intr_register_int (0x30, 3, INTR_ON, syscall_handler, "syscall");
} }
/*Handler for system commands.*/
static void static void
syscall_handler (struct intr_frame *f UNUSED) syscall_handler (struct intr_frame *f UNUSED)
{ {
printf ("system call!\n"); /* References: J,Choi(2014), pintos. Available from: https://github.com/wookayin/pintos [accessed on 27/11/22]*/
int syscall_number;
ASSERT( sizeof(syscall_number) == 4 ); /*assuming x86*/
/*The system call number is in the 32-bit word at the caller's stack pointer.*/
read(f->esp, &syscall_number, sizeof(syscall_number));
/*Store the esp, which is needed in the page fault handler.*/
thread_current()->current_esp = f->esp;
switch (syscall_number) {
case SYS_HALT: // 0
{
/*Terminate PintOS*/
syscall_halt();
break;
}
case SYS_WAIT: // 2
{
tid_t tid;
/*Get argument*/
read(f->esp + 4, &tid, sizeof(tid_t));
/*Wait for child process*/
f->eax = syscall_wait(tid);
break;
}
case SYS_CREATE: // 3
{
const char* file_name;
unsigned initial_size;
/*Get file name and size*/
read(f->esp + 4, &file_name, sizeof(file_name));
read(f->esp + 8, &initial_size, sizeof(initial_size));
/*Create file*/
f->eax = syscall_create(file_name, initial_size);
break;
}
case SYS_REMOVE: // 4
{
const char* file_name;
bool return_code;
/*Get file name*/
read(f->esp + 4, &file_name, sizeof(file_name));
/*Remove file*/
f->eax = syscall_remove(file_name);
break;
}
/* Unimplemented system calls */
default:
printf("ERROR: system call ( %d ) has not implemented!\n", syscall_number);
/* Terminate. */
syscall_exit(-1);
break;
}
}
/********SYSTEMCALLS********/
/* Halt */
void syscall_halt(void) {
shutdown_power_off(); /* From shutdown.h */
}
/* Exit */
void syscall_exit(int status) {
struct thread *current_process=thread_current();
current_process->process_exit_status = status;
printf("%s: exit(%d)\n",current_process->name,status);
thread_exit(); thread_exit();
} }
/* Wait */
int syscall_wait(tid_t tid)
{
return process_wait(tid);
}
/* Create File */
bool syscall_create(const char* file_name, unsigned initial_size) {
bool if_created = false;
if( filesys_create(file_name, initial_size)==true){
if_created = true;
}
return if_created;
}
/* Remove File */
bool syscall_remove(const char* file_name) {
bool if_removed = false;
if( filesys_remove(file_name)==true){
if_removed = true;
}
return if_removed;
}
/****OTHER FUNCTIONS****/
static int read(void *src, void *dst, size_t bytes)
{
int32_t value;
size_t i;
for (i = 0; i < bytes; i++)
{
value = get_user(src + i);
if (value == -1) // segfault or invalid memory access
fail_invalid_access();
*(char *)(dst + i) = value & 0xff;
}
return (int)bytes;
}
/* Reads a byte at user virtual address UADDR.
UADDR must be below PHYS_BASE.
Returns the byte value if successful, -1 if a segfault
occurred. */
static int
get_user (const uint8_t *uaddr)
{
if(!is_user_vaddr(uaddr))
return -1;
int result;
asm ("movl $1f, %0; movzbl %1, %0; 1:"
: "=&a" (result) : "m" (*uaddr));
return result;
}
#ifndef USERPROG_SYSCALL_H #ifndef USERPROG_SYSCALL_H
#define USERPROG_SYSCALL_H #define USERPROG_SYSCALL_H
#include "threads/thread.h"
#include <stdbool.h>
#include <stddef.h>
void syscall_init (void); void syscall_init (void);
void syscall_halt(void);
void syscall_exit(int status);
int syscall_wait(tid_t tid);
bool syscall_create(const char* file_name, unsigned initial_size);
bool syscall_remove(const char* file_name);
static int read(void *src, void *dst, size_t bytes);
static int get_user (const uint8_t *uaddr);
#endif /* userprog/syscall.h */ #endif /* userprog/syscall.h */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment