Changes in uspace/srv/loader/main.c [27b76ca:ffa2c8ef] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/loader/main.c
r27b76ca rffa2c8ef 52 52 #include <ipc/services.h> 53 53 #include <ipc/loader.h> 54 #include <ns.h> 54 #include <ipc/ns.h> 55 #include <macros.h> 55 56 #include <loader/pcb.h> 56 #include <entry_point.h>57 57 #include <errno.h> 58 58 #include <async.h> 59 59 #include <str.h> 60 60 #include <as.h> 61 #include <elf/elf.h> 62 #include <elf/elf_load.h> 63 #include <vfs/vfs.h> 64 65 #ifdef CONFIG_RTLD 66 #include <rtld/rtld.h> 67 #include <rtld/dynamic.h> 68 #include <rtld/module.h> 69 70 static int ldr_load_dyn_linked(elf_info_t *p_info); 71 #endif 61 62 #include <elf.h> 63 #include <elf_load.h> 72 64 73 65 #define DPRINTF(...) … … 90 82 91 83 /** Number of preset files */ 92 static unsigned int filc = 0; 84 static int filc = 0; 85 /** Preset files vector */ 86 static fdi_node_t **filv = NULL; 87 /** Buffer holding all preset files */ 88 static fdi_node_t *fil_buf = NULL; 93 89 94 90 static elf_info_t prog_info; 91 static elf_info_t interp_info; 92 93 static bool is_dyn_linked; 95 94 96 95 /** Used to limit number of connections to one. */ 97 96 static bool connected = false; 98 99 #ifdef CONFIG_RTLD100 /** State structure of the dynamic linker. */101 runtime_env_t dload_re;102 static module_t prog_mod;103 #endif104 97 105 98 static void ldr_get_taskid(ipc_callid_t rid, ipc_call_t *request) … … 236 229 static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request) 237 230 { 238 size_t count = IPC_GET_ARG1(*request); 239 240 async_exch_t *vfs_exch = vfs_exchange_begin(); 241 242 for (filc = 0; filc < count; filc++) { 243 ipc_callid_t callid; 244 int fd; 245 246 if (!async_state_change_receive(&callid, NULL, NULL, NULL)) { 247 async_answer_0(callid, EINVAL); 248 break; 249 } 250 async_state_change_finalize(callid, vfs_exch); 251 fd = fd_wait(); 252 assert(fd == (int) filc); 253 } 254 255 vfs_exchange_end(vfs_exch); 256 231 fdi_node_t *buf; 232 size_t buf_size; 233 int rc = async_data_write_accept((void **) &buf, false, 0, 0, 234 sizeof(fdi_node_t), &buf_size); 235 236 if (rc == EOK) { 237 int count = buf_size / sizeof(fdi_node_t); 238 239 /* 240 * Allocate new filv 241 */ 242 fdi_node_t **_filv = (fdi_node_t **) calloc(count + 1, sizeof(fdi_node_t *)); 243 if (_filv == NULL) { 244 free(buf); 245 async_answer_0(rid, ENOMEM); 246 return; 247 } 248 249 /* 250 * Fill the new filv with argument pointers 251 */ 252 int i; 253 for (i = 0; i < count; i++) 254 _filv[i] = &buf[i]; 255 256 _filv[count] = NULL; 257 258 /* 259 * Copy temporary data to global variables 260 */ 261 if (fil_buf != NULL) 262 free(fil_buf); 263 264 if (filv != NULL) 265 free(filv); 266 267 filc = count; 268 fil_buf = buf; 269 filv = _filv; 270 } 271 257 272 async_answer_0(rid, EOK); 258 273 } … … 268 283 int rc; 269 284 270 rc = elf_load_file(pathname, 0, 0,&prog_info);285 rc = elf_load_file(pathname, 0, &prog_info); 271 286 if (rc != EE_OK) { 272 287 DPRINTF("Failed to load executable '%s'.\n", pathname); … … 283 298 284 299 pcb.filc = filc; 300 pcb.filv = filv; 285 301 286 302 if (prog_info.interp == NULL) { 287 303 /* Statically linked program */ 304 is_dyn_linked = false; 288 305 async_answer_0(rid, EOK); 289 306 return 0; 290 307 } 291 308 292 DPRINTF("Binary is dynamically linked.\n"); 293 #ifdef CONFIG_RTLD 294 DPRINTF(" - pcb address: %p\n", &pcb); 295 DPRINTF( "- prog dynamic: %p\n", prog_info.dynamic); 296 297 rc = ldr_load_dyn_linked(&prog_info); 298 #else 299 rc = ENOTSUP; 300 #endif 301 async_answer_0(rid, rc); 309 rc = elf_load_file(prog_info.interp, 0, &interp_info); 310 if (rc != EE_OK) { 311 DPRINTF("Failed to load interpreter '%s.'\n", 312 prog_info.interp); 313 async_answer_0(rid, EINVAL); 314 return 1; 315 } 316 317 is_dyn_linked = true; 318 async_answer_0(rid, EOK); 319 302 320 return 0; 303 321 } 304 322 305 #ifdef CONFIG_RTLD306 307 static int ldr_load_dyn_linked(elf_info_t *p_info)308 {309 runtime_env = &dload_re;310 311 DPRINTF("Load dynamically linked program.\n");312 313 /*314 * First we need to process dynamic sections of the executable315 * program and insert it into the module graph.316 */317 318 DPRINTF("Parse program .dynamic section at %p\n", p_info->dynamic);319 dynamic_parse(p_info->dynamic, 0, &prog_mod.dyn);320 prog_mod.bias = 0;321 prog_mod.dyn.soname = "[program]";322 323 /* Initialize list of loaded modules */324 list_initialize(&runtime_env->modules);325 list_append(&prog_mod.modules_link, &runtime_env->modules);326 327 /* Pointer to program module. Used as root of the module graph. */328 runtime_env->program = &prog_mod;329 330 /* Work around non-existent memory space allocation. */331 runtime_env->next_bias = 0x1000000;332 333 /*334 * Now we can continue with loading all other modules.335 */336 337 DPRINTF("Load all program dependencies\n");338 module_load_deps(&prog_mod);339 340 /*341 * Now relocate/link all modules together.342 */343 344 /* Process relocations in all modules */345 DPRINTF("Relocate all modules\n");346 modules_process_relocs(&prog_mod);347 348 /* Pass runtime evironment pointer through PCB. */349 pcb.rtld_runtime = (void *) runtime_env;350 351 return 0;352 }353 #endif354 323 355 324 /** Run the previously loaded program. … … 363 332 const char *cp; 364 333 365 DPRINTF("Set task name\n");366 367 334 /* Set the task name. */ 368 335 cp = str_rchr(pathname, '/'); … … 370 337 task_set_name(cp); 371 338 372 /* Run program */ 373 DPRINTF("Reply OK\n"); 374 async_answer_0(rid, EOK); 375 DPRINTF("Jump to entry point at %p\n", pcb.entry); 376 entry_point_jmp(prog_info.entry, &pcb); 339 if (is_dyn_linked == true) { 340 /* Dynamically linked program */ 341 DPRINTF("Run ELF interpreter.\n"); 342 DPRINTF("Entry point: %p\n", interp_info.entry); 343 344 async_answer_0(rid, EOK); 345 elf_run(&interp_info, &pcb); 346 } else { 347 /* Statically linked program */ 348 async_answer_0(rid, EOK); 349 elf_run(&prog_info, &pcb); 350 } 377 351 378 352 /* Not reached */ … … 384 358 * to execute the loaded program). 385 359 */ 386 static void ldr_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 387 { 360 static void ldr_connection(ipc_callid_t iid, ipc_call_t *icall) 361 { 362 ipc_callid_t callid; 363 ipc_call_t call; 364 int retval; 365 388 366 /* Already have a connection? */ 389 367 if (connected) { … … 398 376 399 377 /* Ignore parameters, the connection is already open */ 378 (void) iid; 400 379 (void) icall; 401 380 402 while (true) { 403 int retval; 404 ipc_call_t call; 405 ipc_callid_t callid = async_get_call(&call); 406 407 if (!IPC_GET_IMETHOD(call)) 381 while (1) { 382 callid = async_get_call(&call); 383 384 switch (IPC_GET_IMETHOD(call)) { 385 case IPC_M_PHONE_HUNGUP: 408 386 exit(0); 409 410 switch (IPC_GET_IMETHOD(call)) {411 387 case LOADER_GET_TASKID: 412 388 ldr_get_taskid(callid, &call); … … 431 407 /* Not reached */ 432 408 default: 433 retval = E INVAL;409 retval = ENOENT; 434 410 break; 435 411 } 436 437 async_answer_0(callid, retval); 412 if (IPC_GET_IMETHOD(call) != IPC_M_PHONE_HUNGUP) { 413 DPRINTF("Responding EINVAL to method %d.\n", 414 IPC_GET_IMETHOD(call)); 415 async_answer_0(callid, EINVAL); 416 } 438 417 } 439 418 } … … 448 427 /* Introduce this task to the NS (give it our task ID). */ 449 428 task_id_t id = task_get_id(); 450 int rc = ns_intro(id);429 int rc = async_req_2_0(PHONE_NS, NS_ID_INTRO, LOWER32(id), UPPER32(id)); 451 430 if (rc != EOK) 452 431 return -1;
Note:
See TracChangeset
for help on using the changeset viewer.