diff options
Diffstat (limited to 'kernel/syscalls.c')
| -rw-r--r-- | kernel/syscalls.c | 120 |
1 files changed, 42 insertions, 78 deletions
diff --git a/kernel/syscalls.c b/kernel/syscalls.c index 9cabf25..e43c509 100644 --- a/kernel/syscalls.c +++ b/kernel/syscalls.c @@ -119,56 +119,57 @@ int syscall_readdir(const char *name,fs_dirent *dirs,int max) return fs_readdir(name,dirs,max); } - -int syscall_execve(char *name, char **argv1, char **env1) +int copy_args(char **in, char **out) { + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"copy_args(0x%08x, 0x%08X)",in,out); + int count=0; + while(in[count]!=NULL) + { + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"args(0x%08x: %s)",in[count],out); + count++; + }; - int temp=0x1; - uint32_t *entry=temp; - temp+=4; - - int env_count=0; - do{env_count++;}while(env1[env_count]!=NULL); - - int arg_count=0; - do{arg_count++;}while(argv1[arg_count]!=NULL); - - char **env=temp; - temp+=sizeof(char **)*(env_count+1); - char **argv=temp; - temp+=sizeof(char **)*(arg_count+1); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"copy_args : count: %d",count); + + char **pos=out; + pos+=sizeof(char **)*(count+1); int i=0; do{ - int l=strlen(env1[i]); - char *env_var=temp; - temp+=sizeof(char *)*(l+1); - memcpy(env_var,env1[i],l+1); - env[i]=env_var; + int l=strlen(in[i]); + char *var=pos; + memcpy(var,in[i],l+1); + pos+=sizeof(char *)*(l+1); + out[i]=var; i++; - }while(env1[i]!=NULL); - env[i]=NULL; + }while(in[i]!=NULL); + out[i]=NULL; - i=0; - do{ - int l=strlen(argv1[i]); - char *arg_var=temp; - temp+=sizeof(char *)*(l+1); - memcpy(arg_var,argv1[i],l+1); - argv[i]=arg_var; - i++; - }while(argv1[i]!=NULL); - argv[i]=NULL; + return count; +} + + +int *entry_global=1; +char **argv_global=10; +char **env_global=300; +char **argv=0x8000000; +char **env=0x8000000+300; +int syscall_execve(char *name, char **argv1, char **env1) +{ #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"execve (name=0x%08X(%s), argvs=0x%08X, env=0x%08X)", name,name,argv1,env1); #endif - + + copy_args(argv1,argv_global); + copy_args(env1,env_global); + uint32_t alloc; - *entry=load_elf(name,&alloc); + *entry_global=load_elf(name,&alloc); + task_set_brk(alloc); - if(!*entry) + if(!*entry_global) { #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"execve: bailing out!"); @@ -179,55 +180,18 @@ int syscall_execve(char *name, char **argv1, char **env1) /* try to move this to asm */ //asm volatile("jmp ."); asm volatile("mov $0x8fff000,%esp"); // set stack at high end of process image - - // TODO: avoid code duplication for argv and env!! - char **env_new=alloc; - alloc+=sizeof(char **)*(env_count+1); - - i=0; - do{ - int l=strlen(env[i]); - char *env_var=alloc; - alloc+=sizeof(char)*l+1; - memcpy(env_var,env[i],l+1); - env_new[i]=env_var; - #ifdef LOG_SYSCALLS - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"envr %d : 0x%08X : %s" ,i,env_new[i],env_new[i]); - #endif - i++; - }while(env[i]!=NULL); - env_new[i]=NULL; + int arg_count=copy_args(argv_global,argv); + copy_args(env_global,env); - char **argv_new=alloc; - alloc+=sizeof(char **)*(arg_count+1); - i=0; - do{ - int l=strlen(argv[i]); - char *arg_var=alloc; - alloc+=sizeof(char)*l+1; - memcpy(arg_var,argv[i],l+1); - argv_new[i]=arg_var; - #ifdef LOG_SYSCALLS - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"arg %d : 0x%08X : %s" ,i,argv_new[i],argv_new[i]); - #endif - i++; - }while(argv[i]!=NULL); - - - #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"argc: %d" ,arg_count); - #endif - - task_set_brk(alloc); - - asm volatile ("push %0" :: "r" (argv_new)); + asm volatile ("push %0" :: "r" (argv)); asm volatile ("push %0" :: "r" (arg_count)); - asm volatile ("push %0" :: "r" (env_new)); + asm volatile ("push %0" :: "r" (env)); // push addr and return to it - asm volatile ("push %0"::"r"(*entry)); + asm volatile ("push %0"::"r"(*entry_global)); asm volatile ("sti"); asm volatile ("ret"); |
