Changeset eb522e8 in mainline for uspace/srv/loader/main.c
- Timestamp:
- 2011-06-01T08:43:42Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8d6c1f1
- Parents:
- 9e2e715 (diff), e51a514 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/loader/main.c
r9e2e715 reb522e8 50 50 #include <fcntl.h> 51 51 #include <sys/types.h> 52 #include <ipc/ipc.h>53 52 #include <ipc/services.h> 54 53 #include <ipc/loader.h> … … 56 55 #include <macros.h> 57 56 #include <loader/pcb.h> 57 #include <entry_point.h> 58 58 #include <errno.h> 59 59 #include <async.h> … … 63 63 #include <elf.h> 64 64 #include <elf_load.h> 65 66 #ifdef CONFIG_RTLD 67 #include <rtld/rtld.h> 68 #include <rtld/dynamic.h> 69 #include <rtld/module.h> 70 71 static int ldr_load_dyn_linked(elf_info_t *p_info); 72 #endif 65 73 66 74 #define DPRINTF(...) … … 90 98 91 99 static elf_info_t prog_info; 92 static elf_info_t interp_info;93 94 static bool is_dyn_linked;95 100 96 101 /** Used to limit number of connections to one. */ 97 static bool connected; 102 static bool connected = false; 103 104 #ifdef CONFIG_RTLD 105 /** State structure of the dynamic linker. */ 106 runtime_env_t dload_re; 107 static module_t prog_mod; 108 #endif 98 109 99 110 static void ldr_get_taskid(ipc_callid_t rid, ipc_call_t *request) … … 106 117 107 118 if (!async_data_read_receive(&callid, &len)) { 108 ipc_answer_0(callid, EINVAL);109 ipc_answer_0(rid, EINVAL);119 async_answer_0(callid, EINVAL); 120 async_answer_0(rid, EINVAL); 110 121 return; 111 122 } … … 115 126 116 127 async_data_read_finalize(callid, &task_id, len); 117 ipc_answer_0(rid, EOK);128 async_answer_0(rid, EOK); 118 129 } 119 130 … … 135 146 } 136 147 137 ipc_answer_0(rid, rc);148 async_answer_0(rid, rc); 138 149 } 139 150 … … 155 166 } 156 167 157 ipc_answer_0(rid, rc);168 async_answer_0(rid, rc); 158 169 } 159 170 … … 188 199 if (_argv == NULL) { 189 200 free(buf); 190 ipc_answer_0(rid, ENOMEM);201 async_answer_0(rid, ENOMEM); 191 202 return; 192 203 } … … 220 231 } 221 232 222 ipc_answer_0(rid, rc);233 async_answer_0(rid, rc); 223 234 } 224 235 … … 244 255 if (_filv == NULL) { 245 256 free(buf); 246 ipc_answer_0(rid, ENOMEM);257 async_answer_0(rid, ENOMEM); 247 258 return; 248 259 } … … 271 282 } 272 283 273 ipc_answer_0(rid, EOK);284 async_answer_0(rid, EOK); 274 285 } 275 286 … … 284 295 int rc; 285 296 286 rc = elf_load_file(pathname, 0, &prog_info);297 rc = elf_load_file(pathname, 0, 0, &prog_info); 287 298 if (rc != EE_OK) { 288 299 DPRINTF("Failed to load executable '%s'.\n", pathname); 289 ipc_answer_0(rid, EINVAL);300 async_answer_0(rid, EINVAL); 290 301 return 1; 291 302 } … … 303 314 if (prog_info.interp == NULL) { 304 315 /* Statically linked program */ 305 is_dyn_linked = false; 306 ipc_answer_0(rid, EOK); 316 async_answer_0(rid, EOK); 307 317 return 0; 308 318 } 309 319 310 rc = elf_load_file(prog_info.interp, 0, &interp_info); 311 if (rc != EE_OK) { 312 DPRINTF("Failed to load interpreter '%s.'\n", 313 prog_info.interp); 314 ipc_answer_0(rid, EINVAL); 315 return 1; 316 } 317 318 is_dyn_linked = true; 319 ipc_answer_0(rid, EOK); 320 320 DPRINTF("Binary is dynamically linked.\n"); 321 #ifdef CONFIG_RTLD 322 DPRINTF(" - pcb address: %p\n", &pcb); 323 DPRINTF( "- prog dynamic: %p\n", prog_info.dynamic); 324 325 rc = ldr_load_dyn_linked(&prog_info); 326 #else 327 rc = ENOTSUP; 328 #endif 329 async_answer_0(rid, rc); 321 330 return 0; 322 331 } 323 332 333 #ifdef CONFIG_RTLD 334 335 static int ldr_load_dyn_linked(elf_info_t *p_info) 336 { 337 runtime_env = &dload_re; 338 339 DPRINTF("Load dynamically linked program.\n"); 340 341 /* 342 * First we need to process dynamic sections of the executable 343 * program and insert it into the module graph. 344 */ 345 346 DPRINTF("Parse program .dynamic section at %p\n", p_info->dynamic); 347 dynamic_parse(p_info->dynamic, 0, &prog_mod.dyn); 348 prog_mod.bias = 0; 349 prog_mod.dyn.soname = "[program]"; 350 351 /* Initialize list of loaded modules */ 352 list_initialize(&runtime_env->modules_head); 353 list_append(&prog_mod.modules_link, &runtime_env->modules_head); 354 355 /* Pointer to program module. Used as root of the module graph. */ 356 runtime_env->program = &prog_mod; 357 358 /* Work around non-existent memory space allocation. */ 359 runtime_env->next_bias = 0x1000000; 360 361 /* 362 * Now we can continue with loading all other modules. 363 */ 364 365 DPRINTF("Load all program dependencies\n"); 366 module_load_deps(&prog_mod); 367 368 /* 369 * Now relocate/link all modules together. 370 */ 371 372 /* Process relocations in all modules */ 373 DPRINTF("Relocate all modules\n"); 374 modules_process_relocs(&prog_mod); 375 376 /* Pass runtime evironment pointer through PCB. */ 377 pcb.rtld_runtime = (void *) runtime_env; 378 379 return 0; 380 } 381 #endif 324 382 325 383 /** Run the previously loaded program. … … 333 391 const char *cp; 334 392 393 DPRINTF("Set task name\n"); 394 335 395 /* Set the task name. */ 336 396 cp = str_rchr(pathname, '/'); … … 338 398 task_set_name(cp); 339 399 340 if (is_dyn_linked == true) { 341 /* Dynamically linked program */ 342 DPRINTF("Run ELF interpreter.\n"); 343 DPRINTF("Entry point: %p\n", interp_info.entry); 344 345 ipc_answer_0(rid, EOK); 346 elf_run(&interp_info, &pcb); 347 } else { 348 /* Statically linked program */ 349 ipc_answer_0(rid, EOK); 350 elf_run(&prog_info, &pcb); 351 } 400 /* Run program */ 401 DPRINTF("Reply OK\n"); 402 async_answer_0(rid, EOK); 403 DPRINTF("Jump to entry point at %p\n", pcb.entry); 404 entry_point_jmp(prog_info.entry, &pcb); 352 405 353 406 /* Not reached */ … … 367 420 /* Already have a connection? */ 368 421 if (connected) { 369 ipc_answer_0(iid, ELIMIT);422 async_answer_0(iid, ELIMIT); 370 423 return; 371 424 } … … 374 427 375 428 /* Accept the connection */ 376 ipc_answer_0(iid, EOK);429 async_answer_0(iid, EOK); 377 430 378 431 /* Ignore parameters, the connection is already open */ … … 383 436 callid = async_get_call(&call); 384 437 385 switch (IPC_GET_ METHOD(call)) {438 switch (IPC_GET_IMETHOD(call)) { 386 439 case IPC_M_PHONE_HUNGUP: 387 440 exit(0); … … 408 461 /* Not reached */ 409 462 default: 410 retval = E NOENT;463 retval = EINVAL; 411 464 break; 412 465 } 413 if ((callid & IPC_CALLID_NOTIFICATION) == 0 && 414 IPC_GET_METHOD(call) != IPC_M_PHONE_HUNGUP) { 415 DPRINTF("Responding EINVAL to method %d.\n", 416 IPC_GET_METHOD(call)); 417 ipc_answer_0(callid, EINVAL); 418 } 466 467 if (IPC_GET_IMETHOD(call) != IPC_M_PHONE_HUNGUP) 468 async_answer_0(callid, retval); 419 469 } 420 470 } … … 424 474 int main(int argc, char *argv[]) 425 475 { 426 ipcarg_t phonead; 427 task_id_t id; 428 int rc; 429 430 connected = false; 431 476 /* Set a handler of incomming connections. */ 477 async_set_client_connection(ldr_connection); 478 432 479 /* Introduce this task to the NS (give it our task ID). */ 433 id = task_get_id();434 rc = async_req_2_0(PHONE_NS, NS_ID_INTRO, LOWER32(id), UPPER32(id));480 task_id_t id = task_get_id(); 481 int rc = async_req_2_0(PHONE_NS, NS_ID_INTRO, LOWER32(id), UPPER32(id)); 435 482 if (rc != EOK) 436 483 return -1; 437 438 /* Set a handler of incomming connections. */439 async_set_client_connection(ldr_connection);440 484 441 485 /* Register at naming service. */ 442 if ( ipc_connect_to_me(PHONE_NS, SERVICE_LOAD, 0, 0, &phonead) != 0)486 if (service_register(SERVICE_LOAD) != EOK) 443 487 return -2; 444 488 445 489 async_manager(); 446 490
Note:
See TracChangeset
for help on using the changeset viewer.