Changeset 302 for trunk/kernel/syscalls/sys_exec.c
- Timestamp:
- Jul 31, 2017, 2:36:48 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_exec.c
r101 r302 1 1 /* 2 2 * sys_exec.c - Kernel function implementing the "exec" system call. 3 * 3 * 4 4 * Authors Alain Greiner (2016,2017) 5 5 * … … 37 37 38 38 39 ////////////////////////////////////////////////i////////////////////////////////////// 39 ////////////////////////////////////////////////i////////////////////////////////////// 40 40 // This static function is called by the sys_exec() function to register the .elf 41 41 // pathname in the exec_info structure, from a string stored in user space. 42 ////////////////////////////////////////////////i////////////////////////////////////// 42 ////////////////////////////////////////////////i////////////////////////////////////// 43 43 // @ exec_info : pointer on the exec_info structure. 44 44 // @ pathname : string containing the path to the .elf file (user space). 45 // return 0 if success / non-zero if one string too long, or too many strings. 45 // return 0 if success / non-zero if one string too long, or too many strings. 46 46 /////////////////////////////////////////////////////////////////////////////////////// 47 47 static error_t process_exec_get_path( exec_info_t * exec_info, 48 48 char * pathname ) 49 49 { 50 uint32_t length; 51 52 // get string length 53 length = hal_strlen_from_uspace( pathname ); 54 55 if( length >= CONFIG_VFS_MAX_PATH_LENGTH ) return EINVAL; 50 error_t error; 56 51 57 52 // copy string to exec_info 58 hal_copy_from_uspace( &exec_info->path[0] , pathname , length ); 53 error = hal_strcpy_from_uspace( &exec_info->path[0] , pathname , 54 CONFIG_VFS_MAX_PATH_LENGTH ); 55 if( error ) 56 return EINVAL; 59 57 60 58 return 0; 61 59 } 62 60 63 ////////////////////////////////////////////////i////////////////////////////////////// 61 ////////////////////////////////////////////////i////////////////////////////////////// 64 62 // This static function is called twice by the sys_exec() function : 65 63 // - to register the main() arguments (args) in the exec_info structure. 66 64 // - to register the environment variables (envs) in the exec_info structure. 67 65 // In both cases the input is an array of string pointers in user space, 68 // and a set of strings in user space. 66 // and a set of strings in user space. 69 67 // We allocate one physical page to store a kernel copy of the array of pointers, 70 68 // we allocate one or several physical pages to store the strings themselve, 71 69 // and register these buffers and the number of strings in the exec_info structure. 72 // The max number of strings is 1024 (for both args and envs). The numbers of pages 70 // The max number of strings is 1024 (for both args and envs). The numbers of pages 73 71 // to store the (args) and (envs) strings are configuration parameters. 74 /////////////////////////////////////////////////////////////////////////////////////// 72 /////////////////////////////////////////////////////////////////////////////////////// 75 73 // @ exec_info : pointer on the exec_info structure. 76 74 // @ is_args : true if called for (args) / false if called for (envs). 77 75 // @ pointers : array of pointers on the strings (in user space). 78 // @ return 0 if success / non-zero if too many strings or no more memory. 76 // @ return 0 if success / non-zero if too many strings or no more memory. 79 77 /////////////////////////////////////////////////////////////////////////////////////// 80 78 static error_t process_exec_get_strings( exec_info_t * exec_info, 81 79 bool_t is_args, 82 80 char ** u_pointers ) 83 81 { 84 82 uint32_t index; // string index … … 96 94 else order = bits_log2( CONFIG_VMM_ENVS_SIZE ); 97 95 98 99 96 req.type = KMEM_PAGE; 97 req.flags = AF_KERNEL | AF_ZERO; 100 98 101 99 // allocate one physical page for kernel array of pointers … … 106 104 107 105 k_pointers = ppm_page2vaddr( page ); 108 106 109 107 // allocate several physical pages to store the strings themselve 110 108 req.type = order; … … 114 112 115 113 k_buf_base = ppm_page2vaddr( page ); 116 117 // copy the array of pointers to kernel buffer 118 hal_copy_from_uspace( k_pointers, 114 115 // copy the array of pointers to kernel buffer 116 hal_copy_from_uspace( k_pointers, 119 117 u_pointers, 120 118 CONFIG_PPM_PAGE_SIZE ); … … 125 123 for( index = 0 ; index < 1024 ; index++ ) 126 124 { 127 if( k_pointers[index] == NULL ) 125 if( k_pointers[index] == NULL ) 128 126 { 129 127 found_null = 1; … … 132 130 133 131 // compute string length 134 135 132 length = hal_strlen_from_uspace( k_pointers[index] ); 133 136 134 // copy the user string to kernel buffer 137 135 hal_copy_from_uspace( k_buf_ptr, … … 146 144 } 147 145 148 // update into exec_info structure 146 // update into exec_info structure 149 147 if( found_null && is_args ) 150 148 { … … 160 158 exec_info->envs_nr = index; 161 159 } 162 else 160 else 163 161 { 164 162 return EINVAL; … … 181 179 { 182 180 exec_info_t exec_info; // structure to pass to process_make_exec() 183 181 error_t error; 184 182 paddr_t paddr; 185 183 186 184 thread_t * this = CURRENT_THREAD; 187 185 process_t * process = this->process; 188 186 189 187 // check argument fileme 190 188 error = vmm_v2p_translate( false , filename , &paddr ); 191 189 192 190 if( error ) 193 191 { 194 192 printk("\n[ERROR] in %s : filename unmapped\n", __FUNCTION__ ); … … 200 198 error = vmm_v2p_translate( false , args , &paddr ); 201 199 202 200 if( error ) 203 201 { 204 202 printk("\n[ERROR] in %s : args unmapped\n", __FUNCTION__ ); … … 210 208 error = vmm_v2p_translate( false , envs , &paddr ); 211 209 212 210 if( error ) 213 211 { 214 212 printk("\n[ERROR] in %s : envs unmapped\n", __FUNCTION__ ); … … 224 222 exec_dmsg("\n[INFO] %s starts for process %x on core %d in cluster %x" 225 223 " / target_cluster = %x / cycle %d\n", 226 __FUNCTION__, process->pid , CURRENT_CORE->lid, 224 __FUNCTION__, process->pid , CURRENT_CORE->lid, 227 225 cxy_client, cxy_server, hal_get_cycles()); 228 226 229 // register reference parent process in exec_info 227 // register reference parent process in exec_info 230 228 exec_info.parent_xp = process->ref_xp; 231 229 232 233 234 235 230 // check pathname and store it in exec_info structure 231 error = process_exec_get_path( &exec_info , filename ); 232 233 if ( error ) 236 234 { 237 235 printk("\n[ERROR] in %s : elf pathname too long\n", __FUNCTION__ ); … … 240 238 } 241 239 242 243 244 245 if( error ) 240 // check and store args in exec_info structure 241 error = process_exec_get_strings( &exec_info , true , args ); 242 243 if( error ) 246 244 { 247 245 printk("\n[ERROR] in %s : cannot access args\n", __FUNCTION__ ); … … 249 247 return -1; 250 248 } 251 252 253 254 255 249 250 // check and store envs in exec_info structure 251 error = process_exec_get_strings( &exec_info , false , envs ); 252 253 if( error ) 256 254 { 257 255 printk("\n[ERROR] in %s : cannot access envs\n", __FUNCTION__ ); … … 259 257 return -1; 260 258 } 261 259 262 260 exec_dmsg("\n[INFO] %s starts exec for process %x at cycle %d\n", 263 261 __FUNCTION__, process->pid, hal_get_cycles() );
Note: See TracChangeset
for help on using the changeset viewer.