Thomas Lovén 1693baaf6b [USER] Init libc with arguments and environment
MESS - execve - Clean up and move earlier
2017-03-27 23:09:09 +02:00

81 lines
1.7 KiB
C

#include <elf.h>
#include <stdint.h>
#include <debug.h>
#include <mem.h>
#include <string.h>
#include <process.h>
thread_t *exec_elf(process_t *p, void *image, char *argv[], char *envp[])
{
int argc = 0, envc=0;
// Count strings and save their lengths
int len = 0;
while(argv[argc]){
len += strlen(argv[argc]) + 1;
argc++;
}
len += (argc+1)*sizeof(char *);
while(envp[envc])
{
len += strlen(envp[envc]) + 1;
envc++;
}
len += (envc+1)*sizeof(char *);
len += sizeof(size_t)*2;
len += sizeof(char);
// Replace process memory space with new image
void *entry = load_elf(p, image);
procmm_setup(p, len);
// We will write to process memory, so let's switch to it
vmm_set_P4(p->mmap->P4);
// Memory layout of area before BRK
// argv[]
// 0
// envp[]
// 0
// auxv[]
// arguments
// env strings
// 0
// BRK points here
void *pos = (void *)p->mmap->brk->start;
char **_argv = pos;
pos = incptr(pos, (argc+1)*sizeof(char *));
char **_envp = pos;
pos = incptr(pos, (envc+1)*sizeof(char *));
size_t *_auxv = pos;
pos = incptr(pos, sizeof(size_t)*2);
// Copy arguments
for(int i = 0; i < argc; i++)
{
size_t len = strlen(argv[i]) + 1;
_argv[i] = pos;
memcpy(_argv[i], argv[i], len);
pos = incptr(pos, len);
}
_argv[argc] = 0;
// Copy environment strings
for(int i = 0; i < envc; i++)
{
size_t len = strlen(envp[i]) + 1;
_envp[i] = pos;
memcpy(_envp[i], envp[i], len);
pos = incptr(pos, len);
}
_envp[envc] = 0;
// No auxiliary vectors for now
_auxv[0] = 0;
thread_t *th = new_thread((void *)entry, 1);
process_attach(p, th);
th->r.rsi = (uint64_t)_argv;
th->r.rdi = argc;
return th;
}