Skip to content

Commit

Permalink
x86_64: pass arguments to new program's context
Browse files Browse the repository at this point in the history
  • Loading branch information
jewelcodes committed Oct 1, 2024
1 parent 2a073f8 commit 45ca65a
Showing 1 changed file with 45 additions and 2 deletions.
47 changes: 45 additions & 2 deletions src/platform/x86_64/sched/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,57 @@ int platformSetContext(Thread *t, uintptr_t entry, uintptr_t highest, const char
ctx->regs.rdi = (uint64_t)argv;
ctx->regs.rsi = (uint64_t)envp;

// allocate a user stack
// allocate memory for the arguments and environmental variables
uintptr_t base = highest;
while(base % PAGE_SIZE) {
base++;
}

base += PAGE_SIZE; // guard page

// parse args
if(argv) {
int argc;
for(argc = 0; argv[argc]; argc++);

uintptr_t *args = (uintptr_t *) vmmAllocate(base, USER_LIMIT_ADDRESS, 1, VMM_WRITE | VMM_USER);
if(!args) return -1;

ctx->regs.rdi = (uint64_t) args;

// copy args
for(int i = 0; argc && i < argc; i++) {
args[i] = vmmAllocate(base, USER_LIMIT_ADDRESS, 1, VMM_WRITE | VMM_USER);
if(!args[i]) return -1;
strcpy((char *) args[i], argv[i]);
}

// and null terminate
args[argc] = 0;
}

// likewise for the env variables
if(envp) {
int envc;
for(envc = 0; envp[envc]; envc++);

uintptr_t *envs = (uintptr_t *) vmmAllocate(base, USER_LIMIT_ADDRESS, 1, VMM_WRITE | VMM_USER);
if(!envs) return -1;

ctx->regs.rsi = (uint64_t) envs;

// copy env variables
for(int i = 0; envc && i < envc; i++) {
envs[i] = vmmAllocate(base, USER_LIMIT_ADDRESS, 1, VMM_WRITE | VMM_USER);
if(!envs[i]) return -1;
strcpy((void *) envs[i], envp[i]);
}

// and null terminate
envs[envc] = 0;
}

// now allocate a stack
size_t pages = (PLATFORM_THREAD_STACK+PAGE_SIZE-1)/PAGE_SIZE;
pages++;

Expand All @@ -158,7 +201,7 @@ int platformSetContext(Thread *t, uintptr_t entry, uintptr_t highest, const char
stack += PLATFORM_THREAD_STACK;
ctx->regs.rsp = stack;

t->highest = stack + PAGE_SIZE; // requisite to sbrk() someday
t->highest = stack + PAGE_SIZE; // requisite to sbrk()

t->pages = (t->highest - USER_BASE_ADDRESS + PAGE_SIZE - 1) / PAGE_SIZE;
return 0;
Expand Down

0 comments on commit 45ca65a

Please sign in to comment.