i hate this job
This commit is contained in:
parent
4e5c2e960d
commit
ed609d68b7
1 changed files with 93 additions and 4 deletions
|
@ -17,6 +17,18 @@
|
|||
#include "threads/palloc.h"
|
||||
#include "threads/thread.h"
|
||||
#include "threads/vaddr.h"
|
||||
#include "lib/kernel/list.h"
|
||||
|
||||
static struct arg {
|
||||
struct list_elem elem;
|
||||
char* data;
|
||||
void* addr;
|
||||
};
|
||||
|
||||
struct arguments {
|
||||
int argc;
|
||||
char** argv;
|
||||
};
|
||||
|
||||
static thread_func start_process NO_RETURN;
|
||||
static bool load (const char *cmdline, void (**eip) (void), void **esp);
|
||||
|
@ -50,19 +62,96 @@ process_execute (const char *file_name)
|
|||
static void
|
||||
start_process (void *file_name_)
|
||||
{
|
||||
char *file_name = file_name_;
|
||||
char *cmdline = file_name_;
|
||||
|
||||
struct intr_frame if_;
|
||||
bool success;
|
||||
|
||||
// Populate the stack
|
||||
struct list arg_list;
|
||||
list_init(&arg_list);
|
||||
|
||||
char *token, *save_ptr;
|
||||
|
||||
// tokenize cmdline
|
||||
for (token = strtok_r(cmdline, " ", &save_ptr); token != NULL;
|
||||
token = strtok_r(NULL, " ", &save_ptr)) {
|
||||
struct arg* it = malloc(sizeof(struct arg));
|
||||
it->data = token;
|
||||
printf("list_elem pushed: %s\n", token);
|
||||
list_push_back(&arg_list, it);
|
||||
}
|
||||
|
||||
list_reverse(&arg_list);
|
||||
|
||||
printf("ciao mamma!\n");
|
||||
struct list_elem* e;
|
||||
for (e = list_begin(&arg_list); e != list_end(&arg_list); e = list_next(e)) {
|
||||
struct arg* i = list_entry(e, struct arg, elem);
|
||||
printf("list_elem: %s\n", i->data);
|
||||
}
|
||||
|
||||
// put argv[i][...] on stack and keep track of addresses
|
||||
char* program_name;
|
||||
for (e = list_begin(&arg_list); e != list_end(&arg_list); e = list_next(e)) {
|
||||
struct arg* i = list_entry(e, struct arg, elem);
|
||||
size_t bytes = strlen(i->data) + 1;
|
||||
if_.esp -= bytes;
|
||||
i->addr = if_.esp;
|
||||
memcpy(&(if_.esp), i->data, bytes);
|
||||
}
|
||||
|
||||
// put terminator of argv[] (argv[4] in example)
|
||||
size_t bytes = sizeof(void*); // size of pointers on stack
|
||||
if_.esp -= bytes;
|
||||
printf("bytes: %d %X\n", bytes, if_.esp);
|
||||
|
||||
{
|
||||
uint32_t write[1] = {0};
|
||||
memcpy(&(if_.esp), write, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
// put addresses of argv[i] on stack
|
||||
for (e = list_begin(&arg_list); e != list_end(&arg_list);) {
|
||||
struct arg* i = list_entry(e, struct arg, elem);
|
||||
if_.esp -= bytes;
|
||||
{
|
||||
uint32_t write[1] = {i->addr};
|
||||
memcpy(&(if_.esp), write, sizeof(uint32_t));
|
||||
}
|
||||
e = list_next(e);
|
||||
|
||||
}
|
||||
|
||||
//put argv
|
||||
if_.esp -= bytes;
|
||||
{
|
||||
uint32_t write[1] = {if_.esp + bytes};
|
||||
memcpy(&(if_.esp), write, sizeof(uint32_t));
|
||||
}
|
||||
//put argc
|
||||
if_.esp -= bytes;
|
||||
{
|
||||
uint32_t write[1] = {list_size(&arg_list) - 1};
|
||||
memcpy(&(if_.esp), write, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
//put return address
|
||||
if_.esp -= bytes;
|
||||
{
|
||||
uint32_t write[1] = {0};
|
||||
memcpy(&(if_.esp), write, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
/* Initialize interrupt frame and load executable. */
|
||||
memset (&if_, 0, sizeof if_);
|
||||
if_.gs = if_.fs = if_.es = if_.ds = if_.ss = SEL_UDSEG;
|
||||
if_.cs = SEL_UCSEG;
|
||||
if_.eflags = FLAG_IF | FLAG_MBS;
|
||||
success = load (file_name, &if_.eip, &if_.esp);
|
||||
success = load (program_name, &if_.eip, &if_.esp);
|
||||
|
||||
/* If load failed, quit. */
|
||||
palloc_free_page (file_name);
|
||||
palloc_free_page (program_name);
|
||||
if (!success)
|
||||
thread_exit ();
|
||||
|
||||
|
|
Reference in a new issue