Changes in / [0dc2fec:af2254ec] in mainline
- Files:
-
- 2 deleted
- 30 edited
Legend:
- Unmodified
- Added
- Removed
-
.bzrignore
r0dc2fec raf2254ec 35 35 uspace/app/devctl/devctl 36 36 uspace/app/dltest/dltest 37 uspace/app/dltests/dltests38 37 uspace/app/dnscfg/dnscfg 39 38 uspace/app/dnsres/dnsres … … 97 96 uspace/dist/app/devctl 98 97 uspace/dist/app/dltest 99 uspace/dist/app/dltests100 98 uspace/dist/app/dnscfg 101 99 uspace/dist/app/dnsres -
abi/include/abi/elf.h
r0dc2fec raf2254ec 157 157 #define STT_SECTION 3 158 158 #define STT_FILE 4 159 #define STT_TLS 6160 159 #define STT_LOPROC 13 161 160 #define STT_HIPROC 15 … … 171 170 #define PT_SHLIB 5 172 171 #define PT_PHDR 6 173 #define PT_TLS 7174 172 #define PT_LOPROC 0x70000000 175 173 #define PT_HIPROC 0x7fffffff -
boot/Makefile.common
r0dc2fec raf2254ec 226 226 ifeq ($(CONFIG_BUILD_SHARED_LIBS), y) 227 227 RD_APPS_NON_ESSENTIAL += \ 228 $(USPACE_PATH)/app/dltest/dltest \ 229 $(USPACE_PATH)/app/dltests/dltests 228 $(USPACE_PATH)/app/dltest/dltest 230 229 endif 231 230 -
kernel/generic/src/lib/elf.c
r0dc2fec raf2254ec 163 163 case PT_LOAD: 164 164 return load_segment(entry, elf, as); 165 case PT_TLS:166 break;167 165 case PT_DYNAMIC: 168 166 case PT_INTERP: -
uspace/Makefile
r0dc2fec raf2254ec 41 41 app/corecfg \ 42 42 app/devctl \ 43 app/dltest \ 43 44 app/dnscfg \ 44 45 app/dnsres \ … … 166 167 drv/platform/icp 167 168 168 169 169 ## Platform-specific hardware support 170 170 # … … 210 210 drv/fb/amdm37x_dispc \ 211 211 srv/hw/irc/icp-ic 212 endif213 214 ## Dynamic linking tests215 #216 ifeq ($(CONFIG_BUILD_SHARED_LIBS),y)217 DIRS += \218 app/dltest \219 app/dltests220 212 endif 221 213 -
uspace/Makefile.common
r0dc2fec raf2254ec 191 191 ifeq ($(STATIC_BUILD),y) 192 192 BASE_LIBS = $(LIBC_PREFIX)/libc.a $(LIBSOFTINT_PREFIX)/libsoftint.a 193 LINKER_SCRIPT ?= $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld 193 194 ifeq ($(MATH),y) 194 195 BASE_LIBS += $(LIBMATH_PREFIX)/libmath.a … … 196 197 else 197 198 BASE_LIBS = $(LIBC_PREFIX)/libc.so.0 $(LIBSOFTINT_PREFIX)/libsoftint.so.0 198 LINK_DYNAMIC = y 199 LFLAGS += -Bdynamic 200 LINKER_SCRIPT ?= $(LIBC_PREFIX)/arch/$(UARCH)/_link-dlexe.ld 199 201 ifeq ($(MATH),y) 200 202 BASE_LIBS += $(LIBMATH_PREFIX)/libmath.so.0 201 203 endif 202 endif203 204 ifeq ($(LINK_DYNAMIC),y)205 LFLAGS += -Bdynamic206 LINKER_SCRIPT ?= $(LIBC_PREFIX)/arch/$(UARCH)/_link-dlexe.ld207 else208 LINKER_SCRIPT ?= $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld209 204 endif 210 205 -
uspace/app/dltest/Makefile
r0dc2fec raf2254ec 28 28 29 29 USPACE_PREFIX = ../.. 30 EXTRA_CFLAGS = -I$(LIBDLTEST_PREFIX) -DDLTEST_LINKED 31 LIBS = $(LIBDLTEST_PREFIX)/libdltest.so.0.0 32 # Need a dynamic link, but possibly still use static libc 33 LINK_DYNAMIC = y 34 30 EXTRA_CFLAGS = -I$(LIBDLTEST_PREFIX) 35 31 BINARY = dltest 36 32 -
uspace/app/dltest/dltest.c
r0dc2fec raf2254ec 43 43 44 44 /** libdltest library handle */ 45 static void *handle; 46 47 /** If true, do not run dlfcn tests */ 48 static bool no_dlfcn = false; 45 void *handle; 49 46 50 47 /** Test dlsym() function */ … … 96 93 { 97 94 int (*p_dl_get_private_var)(void); 98 int *(*p_dl_get_private_var_addr)(void);99 95 int val; 100 96 … … 107 103 } 108 104 109 p_dl_get_private_var_addr = dlsym(handle, "dl_get_private_var_addr");110 if (p_dl_get_private_var_addr == NULL) {111 printf("FAILED\n");112 return false;113 }114 115 105 val = p_dl_get_private_var(); 116 106 117 107 printf("Got %d, expected %d... ", val, dl_private_var_val); 118 108 if (val != dl_private_var_val) { 119 printf("dl_get_private_var_addr -> %p\n",120 p_dl_get_private_var_addr());121 109 printf("FAILED\n"); 122 110 return false; … … 133 121 { 134 122 int (*p_dl_get_private_uvar)(void); 135 int *(*p_dl_get_private_uvar_addr)(void);136 123 int val; 137 124 … … 144 131 } 145 132 146 p_dl_get_private_uvar_addr = dlsym(handle, "dl_get_private_uvar_addr");147 if (p_dl_get_private_uvar_addr == NULL) {148 printf("FAILED\n");149 return false;150 }151 152 133 val = p_dl_get_private_uvar(); 153 134 154 135 printf("Got %d, expected %d... ", val, 0); 155 136 if (val != 0) { 156 printf("dl_get_private_uvar_addr -> %p\n",157 p_dl_get_private_uvar_addr());158 137 printf("FAILED\n"); 159 138 return false; … … 170 149 { 171 150 int (*p_dl_get_public_var)(void); 172 int *(*p_dl_get_public_var_addr)(void);173 151 int val; 174 152 … … 181 159 } 182 160 183 p_dl_get_public_var_addr = dlsym(handle, "dl_get_public_var_addr");184 if (p_dl_get_public_var_addr == NULL) {185 printf("FAILED\n");186 return false;187 }188 189 161 val = p_dl_get_public_var(); 190 162 191 163 printf("Got %d, expected %d... ", val, dl_public_var_val); 192 164 if (val != dl_public_var_val) { 193 printf("dl_get_public_var_addr -> %p\n",194 p_dl_get_public_var_addr());195 165 printf("FAILED\n"); 196 166 return false; … … 207 177 { 208 178 int (*p_dl_get_public_uvar)(void); 209 int *(*p_dl_get_public_uvar_addr)(void);210 179 int val; 211 180 … … 218 187 } 219 188 220 p_dl_get_public_uvar_addr = dlsym(handle, "dl_get_public_uvar_addr");221 if (p_dl_get_public_uvar_addr == NULL) {222 printf("FAILED\n");223 return false;224 }225 226 189 val = p_dl_get_public_uvar(); 227 190 228 191 printf("Got %d, expected %d... ", val, 0); 229 192 if (val != 0) { 230 printf("dl_get_public_uvar_addr -> %p\n",231 p_dl_get_public_uvar_addr());232 193 printf("FAILED\n"); 233 194 return false; … … 244 205 { 245 206 int *p_dl_public_var; 246 int *(*p_dl_get_public_var_addr)(void);247 207 int val; 248 208 … … 255 215 } 256 216 257 p_dl_get_public_var_addr = dlsym(handle, "dl_get_public_var_addr");258 if (p_dl_get_public_var_addr == NULL) {259 printf("FAILED\n");260 return false;261 }262 263 217 val = *p_dl_public_var; 264 218 265 219 printf("Got %d, expected %d... ", val, dl_public_var_val); 266 220 if (val != dl_public_var_val) { 267 printf("&dl_public_var = %p, "268 "dl_get_public_var_addr -> %p\n",269 p_dl_public_var, p_dl_get_public_var_addr());270 221 printf("FAILED\n"); 271 222 return false; … … 282 233 { 283 234 int *p_dl_public_uvar; 284 int *(*p_dl_get_public_uvar_addr)(void);285 235 int val; 286 236 … … 293 243 } 294 244 295 p_dl_get_public_uvar_addr = dlsym(handle, "dl_get_public_uvar_addr");296 if (p_dl_get_public_uvar_addr == NULL) {297 printf("FAILED\n");298 return false;299 }300 301 245 val = *p_dl_public_uvar; 302 246 303 247 printf("Got %d, expected %d... ", val, 0); 304 248 if (val != 0) { 305 printf("&dl_public_uvar = %p, " 306 "dl_get_public_uvar_addr -> %p\n", 307 p_dl_public_uvar, p_dl_get_public_uvar_addr()); 308 printf("FAILED\n"); 309 return false; 310 } 311 312 printf("Passed\n"); 313 return true; 314 } 315 316 #ifndef STATIC_EXE 317 318 /** Test calling a function that returns contents of a private initialized 319 * fibril-local variable. 320 */ 321 static bool test_dlfcn_dl_get_private_fib_var(void) 322 { 323 int (*p_dl_get_private_fib_var)(void); 324 int *(*p_dl_get_private_fib_var_addr)(void); 325 int val; 326 327 printf("Call dlsym/dl_get_private_fib_var...\n"); 328 329 p_dl_get_private_fib_var = dlsym(handle, "dl_get_private_fib_var"); 330 if (p_dl_get_private_fib_var == NULL) { 331 printf("FAILED\n"); 332 return false; 333 } 334 335 p_dl_get_private_fib_var_addr = dlsym(handle, "dl_get_private_fib_var_addr"); 336 if (p_dl_get_private_fib_var_addr == NULL) { 337 printf("FAILED\n"); 338 return false; 339 } 340 341 val = p_dl_get_private_fib_var(); 342 343 printf("Got %d, expected %d... ", val, dl_private_fib_var_val); 344 if (val != dl_private_fib_var_val) { 345 printf("dl_get_private_fib_var_addr -> %p\n", 346 p_dl_get_private_fib_var_addr()); 347 printf("FAILED\n"); 348 return false; 349 } 350 351 printf("Passed\n"); 352 return true; 353 } 354 355 /** Test calling a function that returns contents of a private uninitialized 356 * fibril-local variable. 357 */ 358 static bool test_dlfcn_dl_get_private_fib_uvar(void) 359 { 360 int (*p_dl_get_private_fib_uvar)(void); 361 int *(*p_dl_get_private_fib_uvar_addr)(void); 362 int val; 363 364 printf("Call dlsym/dl_get_private_fib_uvar...\n"); 365 366 p_dl_get_private_fib_uvar = dlsym(handle, "dl_get_private_fib_uvar"); 367 if (p_dl_get_private_fib_uvar == NULL) { 368 printf("FAILED\n"); 369 return false; 370 } 371 372 p_dl_get_private_fib_uvar_addr = dlsym(handle, "dl_get_private_fib_uvar_addr"); 373 if (p_dl_get_private_fib_uvar_addr == NULL) { 374 printf("FAILED\n"); 375 return false; 376 } 377 378 val = p_dl_get_private_fib_uvar(); 379 380 printf("Got %d, expected %d... ", val, 0); 381 if (val != 0) { 382 printf("dl_get_private_fib_uvar_addr -> %p\n", 383 p_dl_get_private_fib_uvar_addr()); 384 printf("FAILED\n"); 385 return false; 386 } 387 388 printf("Passed\n"); 389 return true; 390 } 391 392 /** Test calling a function that returns the contents of a public initialized 393 * fibril-local variable. 394 */ 395 static bool test_dlfcn_dl_get_public_fib_var(void) 396 { 397 int (*p_dl_get_public_fib_var)(void); 398 int *(*p_dl_get_public_fib_var_addr)(void); 399 int val; 400 401 printf("Call dlsym/dl_get_public_fib_var...\n"); 402 403 p_dl_get_public_fib_var = dlsym(handle, "dl_get_public_fib_var"); 404 if (p_dl_get_public_fib_var == NULL) { 405 printf("FAILED\n"); 406 return false; 407 } 408 409 p_dl_get_public_fib_var_addr = dlsym(handle, "dl_get_public_fib_var_addr"); 410 if (p_dl_get_public_fib_var_addr == NULL) { 411 printf("FAILED\n"); 412 return false; 413 } 414 415 val = p_dl_get_public_fib_var(); 416 417 printf("Got %d, expected %d... ", val, dl_public_fib_var_val); 418 if (val != dl_public_fib_var_val) { 419 printf("dl_get_public_fib_var_addr -> %p\n", 420 p_dl_get_public_fib_var_addr()); 421 printf("FAILED\n"); 422 return false; 423 } 424 425 printf("Passed\n"); 426 return true; 427 } 428 429 /** Test calling a function that returns the contents of a public uninitialized 430 * fibril-local variable. 431 */ 432 static bool test_dlfcn_dl_get_public_fib_uvar(void) 433 { 434 int (*p_dl_get_public_fib_uvar)(void); 435 int *(*p_dl_get_public_fib_uvar_addr)(void); 436 int val; 437 438 printf("Call dlsym/dl_get_public_fib_uvar...\n"); 439 440 p_dl_get_public_fib_uvar = dlsym(handle, "dl_get_public_fib_uvar"); 441 if (p_dl_get_public_fib_uvar == NULL) { 442 printf("FAILED\n"); 443 return false; 444 } 445 446 p_dl_get_public_fib_uvar_addr = dlsym(handle, "dl_get_public_fib_uvar_addr"); 447 if (p_dl_get_public_fib_uvar_addr == NULL) { 448 printf("FAILED\n"); 449 return false; 450 } 451 452 val = p_dl_get_public_fib_uvar(); 453 454 printf("Got %d, expected %d... ", val, 0); 455 if (val != 0) { 456 printf("dl_get_public_fib_uvar_addr -> %p\n", 457 p_dl_get_public_fib_uvar_addr()); 458 printf("FAILED\n"); 459 return false; 460 } 461 462 printf("Passed\n"); 463 return true; 464 } 465 466 /** Test directly reading a public initialized fibril-local variable 467 * whose address was obtained using dlsym. 468 */ 469 static bool test_dlfcn_read_public_fib_var(void) 470 { 471 int *p_dl_public_fib_var; 472 int *(*p_dl_get_public_fib_var_addr)(void); 473 int val; 474 475 printf("Read dlsym/dl_public_fib_var...\n"); 476 477 p_dl_public_fib_var = dlsym(handle, "dl_public_fib_var"); 478 if (p_dl_public_fib_var == NULL) { 479 printf("FAILED\n"); 480 return false; 481 } 482 483 p_dl_get_public_fib_var_addr = dlsym(handle, "dl_get_public_fib_var_addr"); 484 if (p_dl_get_public_fib_var_addr == NULL) { 485 printf("FAILED\n"); 486 return false; 487 } 488 489 val = *p_dl_public_fib_var; 490 491 printf("Got %d, expected %d... ", val, dl_public_fib_var_val); 492 if (val != dl_public_fib_var_val) { 493 printf("&dl_public_fib_var = %p, " 494 "dl_get_public_fib_var_addr -> %p\n", 495 p_dl_public_fib_var, p_dl_get_public_fib_var_addr()); 496 printf("FAILED\n"); 497 return false; 498 } 499 500 printf("Passed\n"); 501 return true; 502 } 503 504 /** Test directly reading a public uninitialized fibril-local variable 505 * whose address was obtained using dlsym. 506 */ 507 static bool test_dlfcn_read_public_fib_uvar(void) 508 { 509 int *p_dl_public_fib_uvar; 510 int *(*p_dl_get_public_fib_uvar_addr)(void); 511 int val; 512 513 printf("Read dlsym/dl_public_fib_uvar...\n"); 514 515 p_dl_public_fib_uvar = dlsym(handle, "dl_public_fib_uvar"); 516 if (p_dl_public_fib_uvar == NULL) { 517 printf("FAILED\n"); 518 return false; 519 } 520 521 p_dl_get_public_fib_uvar_addr = dlsym(handle, "dl_get_public_fib_uvar_addr"); 522 if (p_dl_get_public_fib_uvar_addr == NULL) { 523 printf("FAILED\n"); 524 return false; 525 } 526 527 val = *p_dl_public_fib_uvar; 528 529 printf("Got %d, expected %d... ", val, 0); 530 if (val != 0) { 531 printf("&dl_public_fib_uvar = %p, " 532 "dl_get_public_fib_uvar_addr -> %p\n", 533 p_dl_public_fib_uvar, p_dl_get_public_fib_uvar_addr()); 534 printf("FAILED\n"); 535 return false; 536 } 537 538 printf("Passed\n"); 539 return true; 540 } 541 542 #endif /* STATIC_EXE */ 543 544 #ifdef DLTEST_LINKED 545 546 /** Test directly calling function that returns a constant */ 547 static bool test_lnk_dl_get_constant(void) 548 { 549 int val; 550 551 printf("Call linked dl_get_constant...\n"); 552 553 val = dl_get_constant(); 554 555 printf("Got %d, expected %d... ", val, dl_constant); 556 if (val != dl_constant) { 557 printf("FAILED\n"); 558 return false; 559 } 560 561 printf("Passed\n"); 562 return true; 563 } 564 565 /** Test dircetly calling a function that returns contents of a private 566 * initialized variable. 567 */ 568 static bool test_lnk_dl_get_private_var(void) 569 { 570 int val; 571 572 printf("Call linked dl_get_private_var...\n"); 573 574 val = dl_get_private_var(); 575 576 printf("Got %d, expected %d... ", val, dl_private_var_val); 577 if (val != dl_private_var_val) { 578 printf("dl_get_private_var_addr -> %p\n", 579 dl_get_private_var_addr()); 580 printf("FAILED\n"); 581 return false; 582 } 583 584 printf("Passed\n"); 585 return true; 586 } 587 588 /** Test dircetly calling a function that returns contents of a private 589 * uninitialized variable. 590 */ 591 static bool test_lnk_dl_get_private_uvar(void) 592 { 593 int val; 594 595 printf("Call linked dl_get_private_uvar...\n"); 596 597 val = dl_get_private_uvar(); 598 599 printf("Got %d, expected %d... ", val, 0); 600 if (val != 0) { 601 printf("dl_get_private_uvar_addr -> %p\n", 602 dl_get_private_uvar_addr()); 603 printf("FAILED\n"); 604 return false; 605 } 606 607 printf("Passed\n"); 608 return true; 609 } 610 611 /** Test directly calling a function that returns the contents of a public 612 * initialized variable. 613 */ 614 static bool test_lnk_dl_get_public_var(void) 615 { 616 int val; 617 618 printf("Call linked dl_get_public_var...\n"); 619 620 val = dl_get_public_var(); 621 622 printf("Got %d, expected %d... ", val, dl_public_var_val); 623 if (val != dl_public_var_val) { 624 printf("dl_get_public_var_addr -> %p\n", 625 dl_get_public_var_addr()); 626 printf("FAILED\n"); 627 return false; 628 } 629 630 printf("Passed\n"); 631 return true; 632 } 633 634 /** Test directly calling a function that returns the contents of a public 635 * uninitialized variable. 636 */ 637 static bool test_lnk_dl_get_public_uvar(void) 638 { 639 int val; 640 641 printf("Call linked dl_get_public_uvar...\n"); 642 643 val = dl_get_public_uvar(); 644 645 printf("Got %d, expected %d... ", val, 0); 646 if (val != 0) { 647 printf("dl_get_public_uvar_addr -> %p\n", 648 dl_get_public_uvar_addr()); 649 printf("FAILED\n"); 650 return false; 651 } 652 653 printf("Passed\n"); 654 return true; 655 } 656 657 /** Test directly reading a public initialized variable. */ 658 static bool test_lnk_read_public_var(void) 659 { 660 int val; 661 662 printf("Read linked dl_public_var...\n"); 663 664 val = dl_public_var; 665 666 printf("Got %d, expected %d... ", val, dl_public_var_val); 667 if (val != dl_public_var_val) { 668 printf("&dl_public_var = %p, dl_get_public_var_addr -> %p\n", 669 &dl_public_var, dl_get_public_var_addr()); 670 printf("FAILED\n"); 671 return false; 672 } 673 674 printf("Passed\n"); 675 return true; 676 } 677 678 /** Test directly reading a public uninitialized variable. */ 679 static bool test_lnk_read_public_uvar(void) 680 { 681 int val; 682 683 printf("Read linked dl_public_uvar...\n"); 684 685 val = dl_public_uvar; 686 687 printf("Got %d, expected %d... ", val, 0); 688 if (val != 0) { 689 printf("&dl_public_uvar = %p, dl_get_public_uvar_addr -> %p\n", 690 &dl_public_uvar, dl_get_public_uvar_addr()); 691 printf("FAILED\n"); 692 return false; 693 } 694 695 printf("Passed\n"); 696 return true; 697 } 698 699 /** Test dircetly calling a function that returns contents of a private 700 * initialized fibril-local variable. 701 */ 702 static bool test_lnk_dl_get_private_fib_var(void) 703 { 704 int val; 705 706 printf("Call linked dl_get_private_fib_var...\n"); 707 708 val = dl_get_private_fib_var(); 709 710 printf("Got %d, expected %d... ", val, dl_private_fib_var_val); 711 if (val != dl_private_fib_var_val) { 712 printf("dl_get_private_fib_var_addr -> %p\n", 713 dl_get_private_fib_var_addr()); 714 printf("FAILED\n"); 715 return false; 716 } 717 718 printf("Passed\n"); 719 return true; 720 } 721 722 /** Test dircetly calling a function that returns contents of a private 723 * uninitialized fibril-local variable. 724 */ 725 static bool test_lnk_dl_get_private_fib_uvar(void) 726 { 727 int val; 728 729 printf("Call linked dl_get_private_fib_uvar...\n"); 730 731 val = dl_get_private_fib_uvar(); 732 733 printf("Got %d, expected %d... ", val, 0); 734 if (val != 0) { 735 printf("dl_get_private_fib_uvar_addr -> %p\n", 736 dl_get_private_fib_var_addr()); 737 printf("FAILED\n"); 738 return false; 739 } 740 741 printf("Passed\n"); 742 return true; 743 } 744 745 /** Test directly calling a function that returns the contents of a public 746 * initialized fibril-local variable. 747 */ 748 static bool test_lnk_dl_get_public_fib_var(void) 749 { 750 int val; 751 752 printf("Call linked dl_get_public_fib_var...\n"); 753 754 val = dl_get_public_fib_var(); 755 756 printf("Got %d, expected %d... ", val, dl_public_fib_var_val); 757 if (val != dl_public_fib_var_val) { 758 printf("dl_get_public_fib_var_addr -> %p\n", 759 dl_get_public_fib_var_addr()); 760 printf("FAILED\n"); 761 return false; 762 } 763 764 printf("Passed\n"); 765 return true; 766 } 767 768 /** Test directly calling a function that returns the contents of a public 769 * uninitialized fibril-local variable. 770 */ 771 static bool test_lnk_dl_get_public_fib_uvar(void) 772 { 773 int val; 774 775 printf("Call linked dl_get_public_fib_uvar...\n"); 776 777 val = dl_get_public_fib_uvar(); 778 779 printf("Got %d, expected %d... ", val, 0); 780 if (val != 0) { 781 printf("dl_get_public_fib_uvar_addr -> %p\n", 782 dl_get_public_fib_uvar_addr()); 783 printf("FAILED\n"); 784 return false; 785 } 786 787 printf("Passed\n"); 788 return true; 789 } 790 791 /** Test directly reading a public initialized fibril-local variable. */ 792 static bool test_lnk_read_public_fib_var(void) 793 { 794 int val; 795 796 printf("Read linked dl_public_fib_var...\n"); 797 798 val = dl_public_fib_var; 799 800 printf("Got %d, expected %d... ", val, dl_public_fib_var_val); 801 if (val != dl_public_fib_var_val) { 802 printf("&dl_public_fib_var = %p, " 803 "dl_get_public_fib_var_addr -> %p\n", 804 &dl_public_fib_var, dl_get_public_fib_var_addr()); 805 printf("FAILED\n"); 806 return false; 807 } 808 809 printf("Passed\n"); 810 return true; 811 } 812 813 /** Test directly reading a public uninitialized fibril-local variable. */ 814 static bool test_lnk_read_public_fib_uvar(void) 815 { 816 int val; 817 818 printf("Read linked dl_public_fib_uvar...\n"); 819 820 val = dl_public_fib_uvar; 821 822 printf("Got %d, expected %d... ", val, 0); 823 if (val != 0) { 824 printf("&dl_public_fib_uvar = %p, " 825 "dl_get_public_fib_uvar_addr -> %p\n", 826 &dl_public_fib_uvar, dl_get_public_fib_uvar_addr()); 827 printf("FAILED\n"); 828 return false; 829 } 830 831 printf("Passed\n"); 832 return true; 833 } 834 835 #endif /* DLTEST_LINKED */ 836 837 static int test_dlfcn(void) 838 { 249 printf("FAILED\n"); 250 return false; 251 } 252 253 printf("Passed\n"); 254 return true; 255 } 256 257 int main(int argc, char *argv[]) 258 { 259 260 printf("Dynamic linking test\n"); 261 839 262 printf("dlopen()... "); 840 263 handle = dlopen("libdltest.so.0", 0); … … 870 293 return 1; 871 294 872 #ifndef STATIC_EXE873 if (!test_dlfcn_dl_get_private_fib_var())874 return 1;875 876 if (!test_dlfcn_dl_get_private_fib_uvar())877 return 1;878 879 if (!test_dlfcn_dl_get_public_fib_var())880 return 1;881 882 if (!test_dlfcn_dl_get_public_fib_uvar())883 return 1;884 885 if (!test_dlfcn_read_public_fib_var())886 return 1;887 888 if (!test_dlfcn_read_public_fib_uvar())889 return 1;890 #endif /* STATIC_EXE */891 892 295 // printf("dlclose()... "); 893 296 // dlclose(handle); 894 297 // printf("Passed\n"); 895 298 896 return 0;897 }898 899 #ifdef DLTEST_LINKED900 901 static int test_lnk(void)902 {903 if (!test_lnk_dl_get_constant())904 return 1;905 906 if (!test_lnk_dl_get_private_var())907 return 1;908 909 if (!test_lnk_dl_get_private_uvar())910 return 1;911 912 if (!test_lnk_dl_get_public_var())913 return 1;914 915 if (!test_lnk_dl_get_public_uvar())916 return 1;917 918 if (!test_lnk_read_public_var())919 return 1;920 921 if (!test_lnk_read_public_uvar())922 return 1;923 924 if (!test_lnk_dl_get_private_fib_var())925 return 1;926 927 if (!test_lnk_dl_get_private_fib_uvar())928 return 1;929 930 if (!test_lnk_dl_get_public_fib_var())931 return 1;932 933 if (!test_lnk_dl_get_public_fib_uvar())934 return 1;935 936 if (!test_lnk_read_public_fib_var())937 return 1;938 939 if (!test_lnk_read_public_fib_uvar())940 return 1;941 942 return 0;943 }944 945 #endif /* DLTEST_LINKED */946 947 static void print_syntax(void)948 {949 fprintf(stderr, "syntax: dltest [-n]\n");950 fprintf(stderr, "\t-n Do not run dlfcn tests\n");951 }952 953 int main(int argc, char *argv[])954 {955 printf("Dynamic linking test\n");956 957 if (argc > 1) {958 if (argc > 2) {959 print_syntax();960 return 1;961 }962 963 if (str_cmp(argv[1], "-n") == 0) {964 no_dlfcn = true;965 } else {966 print_syntax();967 return 1;968 }969 }970 971 if (!no_dlfcn) {972 if (test_dlfcn() != 0)973 return 1;974 }975 976 #ifdef DLTEST_LINKED977 if (test_lnk() != 0)978 return 1;979 #endif980 981 299 printf("All passed.\n"); 982 300 return 0; -
uspace/lib/c/arch/ia32/_link.ld.in
r0dc2fec raf2254ec 12 12 #endif 13 13 data PT_LOAD FLAGS(6); 14 tls PT_TLS;15 14 #if defined(SHLIB) || defined(DLEXE) 16 15 dynamic PT_DYNAMIC; … … 96 95 #endif 97 96 97 #ifndef DLEXE 98 98 .tdata : { 99 #ifndef DLEXE100 99 _tdata_start = .; 101 #endif102 100 *(.tdata); 103 101 *(.gnu.linkonce.tb.*); 104 #ifndef DLEXE105 102 _tdata_end = .; 106 #endif107 } :data :tls108 .tbss : {109 #ifndef DLEXE110 103 _tbss_start = .; 111 #endif112 104 *(.tbss); 113 #ifndef DLEXE114 105 _tbss_end = .; 115 #endif 116 } :data :tls 106 } :data 117 107 118 #ifndef DLEXE119 108 _tls_alignment = ALIGNOF(.tdata); 120 109 #endif -
uspace/lib/c/arch/ia32/include/libarch/rtld/elf_dyn.h
r0dc2fec raf2254ec 36 36 #define LIBC_ia32_RTLD_ELF_DYN_H_ 37 37 38 /* 38 /* 39 39 * ia32 dynamic relocation types 40 40 */ … … 47 47 #define R_386_RELATIVE 8 48 48 49 #define R_386_TLS_TPOFF 1450 49 #define R_386_TLS_DTPMOD32 35 51 #define R_386_TLS_DTPOFF32 3652 50 53 51 #endif -
uspace/lib/c/arch/ia32/include/libarch/tls.h
r0dc2fec raf2254ec 43 43 void *self; 44 44 void *fibril_data; 45 void **dtv;46 45 } tcb_t; 47 46 -
uspace/lib/c/arch/ia32/src/rtld/reloc.c
r0dc2fec raf2254ec 101 101 sym_def = symbol_def_find(str_tab + sym->st_name, 102 102 m, ssf_none, &dest); 103 DPRINTF("dest name: '%s'\n", dest->dyn.soname);103 // DPRINTF("dest name: '%s'\n", dest->dyn.soname); 104 104 // DPRINTF("dest bias: 0x%x\n", dest->bias); 105 105 if (sym_def) { 106 106 sym_addr = (uint32_t) 107 symbol_get_addr(sym_def, dest , NULL);107 symbol_get_addr(sym_def, dest); 108 108 // DPRINTF("symbol definition found, addr=0x%x\n", sym_addr); 109 109 } else { … … 115 115 sym_addr = 0; 116 116 sym_def = NULL; 117 118 /*119 * DTPMOD with null st_name should return the index120 * of the current module.121 */122 dest = m;123 117 } 124 118 … … 154 148 if (sym_def) { 155 149 sym_addr = (uint32_t) 156 symbol_get_addr(sym_def, dest , NULL);150 symbol_get_addr(sym_def, dest); 157 151 } else { 158 152 printf("Source definition of '%s' not found.\n", … … 177 171 break; 178 172 179 case R_386_TLS_TPOFF:180 DPRINTF("fixup R_386_TLS_TPOFF\n");181 *r_ptr = (dest->ioffs + sym_def->st_value) - dest->rtld->tls_size;182 break;183 184 case R_386_TLS_DTPOFF32:185 DPRINTF("fixup R_386_TLS_DTPOFF32\n");186 *r_ptr = sym_def->st_value;187 break;188 189 173 case R_386_TLS_DTPMOD32: 190 DPRINTF("fixup R_386_TLS_DTPMOD32\n"); 191 *r_ptr = dest->id; 174 /* 175 * We can ignore this as long as the only module 176 * with TLS variables is libc.so. 177 */ 178 DPRINTF("Ignoring R_386_TLS_DTPMOD32\n"); 192 179 break; 193 180 -
uspace/lib/c/arch/ia32/src/tls.c
r0dc2fec raf2254ec 1 1 /* 2 2 * Copyright (c) 2006 Ondrej Palkovsky 3 * Copyright (c) 2016 Jiri Svoboda4 3 * All rights reserved. 5 4 * … … 40 39 #include <align.h> 41 40 42 #ifdef CONFIG_RTLD43 #include <rtld/rtld.h>44 #endif45 46 41 tcb_t *tls_alloc_arch(void **data, size_t size) 47 42 { … … 69 64 *___tls_get_addr(tls_index *ti) 70 65 { 66 size_t tls_size; 71 67 uint8_t *tls; 72 68 73 #ifdef CONFIG_RTLD 74 if (runtime_env != NULL) { 75 return rtld_tls_get_addr(runtime_env, __tcb_get(), 76 ti->ti_module, ti->ti_offset); 77 } 78 #endif 79 /* Get address of static TLS block */ 80 tls = tls_get(); 69 /* Calculate size of TLS block */ 70 tls_size = ALIGN_UP(&_tbss_end - &_tdata_start, &_tls_alignment); 71 72 /* The TLS block is just before TCB */ 73 tls = (uint8_t *)__tcb_get() - tls_size; 74 81 75 return tls + ti->ti_offset; 82 76 } -
uspace/lib/c/generic/dlfcn.c
r0dc2fec raf2254ec 49 49 module_t *m; 50 50 51 if (runtime_env == NULL) { 52 printf("Dynamic linker not set up -- initializing.\n"); 53 rtld_init_static(); 54 } 55 56 printf("dlopen(\"%s\", %d)\n", path, flag); 57 58 printf("module_find('%s')\n", path); 51 59 m = module_find(runtime_env, path); 52 60 if (m == NULL) { 61 printf("NULL. module_load('%s')\n", path); 53 62 m = module_load(runtime_env, path, mlf_local); 63 printf("module_load_deps(m)\n"); 54 64 module_load_deps(m, mlf_local); 55 65 /* Now relocate. */ 66 printf("module_process_relocs(m)\n"); 56 67 module_process_relocs(m); 68 } else { 69 printf("not NULL\n"); 57 70 } 58 71 … … 68 81 module_t *sm; 69 82 83 printf("dlsym(0x%lx, \"%s\")\n", (long)mod, sym_name); 70 84 sd = symbol_bfs_find(sym_name, (module_t *) mod, &sm); 71 85 if (sd != NULL) { 72 return symbol_get_addr(sd, sm , __tcb_get());86 return symbol_get_addr(sd, sm); 73 87 } 74 88 -
uspace/lib/c/generic/elf/elf_mod.c
r0dc2fec raf2254ec 248 248 } 249 249 250 /** Process TLS program header.251 *252 * @param elf Pointer to loader state buffer.253 * @param hdr TLS program header254 * @param info Place to store TLS info255 */256 static void tls_program_header(elf_ld_t *elf, elf_segment_header_t *hdr,257 elf_tls_info_t *info)258 {259 info->tdata = (void *)((uint8_t *)hdr->p_vaddr + elf->bias);260 info->tdata_size = hdr->p_filesz;261 info->tbss_size = hdr->p_memsz - hdr->p_filesz;262 info->tls_align = hdr->p_align;263 }264 265 250 /** Process segment header. 266 251 * 267 * @param elf Pointer to loader state buffer.268 252 * @param entry Segment header. 269 253 * … … 293 277 case 0x70000000: 294 278 /* FIXME: MIPS reginfo */ 295 break;296 case PT_TLS:297 /* Parse TLS program header */298 tls_program_header(elf, entry, &elf->info->tls);299 DPRINTF("TLS header found at %p\n",300 (void *)((uint8_t *)entry->p_vaddr + elf->bias));301 279 break; 302 280 case PT_SHLIB: -
uspace/lib/c/generic/libc.c
r0dc2fec raf2254ec 41 41 */ 42 42 43 #include <errno.h>44 43 #include <libc.h> 45 44 #include <stdlib.h> … … 69 68 __malloc_init(); 70 69 71 /* Save the PCB pointer */72 __pcb = (pcb_t *) pcb_ptr;73 74 #ifdef CONFIG_RTLD75 if (__pcb != NULL && __pcb->rtld_runtime != NULL) {76 runtime_env = (rtld_t *) __pcb->rtld_runtime;77 } else {78 if (rtld_init_static() != EOK)79 abort();80 }81 #endif82 83 70 fibril_t *fibril = fibril_setup(); 84 71 if (fibril == NULL) … … 87 74 __tcb_set(fibril->tcb); 88 75 76 /* Save the PCB pointer */ 77 __pcb = (pcb_t *) pcb_ptr; 89 78 90 79 #ifdef FUTEX_UPGRADABLE … … 100 89 char **argv; 101 90 91 #ifdef CONFIG_RTLD 92 if (__pcb != NULL && __pcb->rtld_runtime != NULL) { 93 runtime_env = (rtld_t *) __pcb->rtld_runtime; 94 } 95 #endif 102 96 /* 103 97 * Get command line arguments and initialize -
uspace/lib/c/generic/rtld/module.c
r0dc2fec raf2254ec 37 37 #include <adt/list.h> 38 38 #include <elf/elf_load.h> 39 #include <errno.h>40 39 #include <fcntl.h> 41 40 #include <loader/pcb.h> … … 49 48 #include <rtld/rtld_arch.h> 50 49 #include <rtld/module.h> 51 52 /** Create module for static executable.53 *54 * @param rtld Run-time dynamic linker55 * @param rmodule Place to store pointer to new module or @c NULL56 * @return EOK on success, ENOMEM if out of memory57 */58 int module_create_static_exec(rtld_t *rtld, module_t **rmodule)59 {60 module_t *module;61 62 module = calloc(1, sizeof(module_t));63 if (module == NULL)64 return ENOMEM;65 66 module->id = rtld_get_next_id(rtld);67 module->dyn.soname = "[program]";68 69 module->rtld = rtld;70 module->exec = true;71 module->local = true;72 73 module->tdata = &_tdata_start;74 module->tdata_size = &_tdata_end - &_tdata_start;75 module->tbss_size = &_tbss_end - &_tbss_start;76 module->tls_align = (uintptr_t)&_tls_alignment;77 78 list_append(&module->modules_link, &rtld->modules);79 80 if (rmodule != NULL)81 *rmodule = module;82 return EOK;83 }84 50 85 51 /** (Eagerly) process all relocation tables in a module. … … 169 135 170 136 m = calloc(1, sizeof(module_t)); 171 if ( m == NULL) {137 if (!m) { 172 138 printf("malloc failed\n"); 173 139 exit(1); … … 175 141 176 142 m->rtld = rtld; 177 m->id = rtld_get_next_id(rtld);178 179 143 if ((flags & mlf_local) != 0) 180 144 m->local = true; … … 217 181 /* Insert into the list of loaded modules */ 218 182 list_append(&m->modules_link, &rtld->modules); 219 220 /* Copy TLS info */221 m->tdata = info.tls.tdata;222 m->tdata_size = info.tls.tdata_size;223 m->tbss_size = info.tls.tbss_size;224 m->tls_align = info.tls.tls_align;225 226 DPRINTF("tdata at %p size %zu, tbss size %zu\n",227 m->tdata, m->tdata_size, m->tbss_size);228 183 229 184 return m; … … 288 243 } 289 244 290 /** Find module structure by ID. */291 module_t *module_by_id(rtld_t *rtld, unsigned long id)292 {293 list_foreach(rtld->modules, modules_link, module_t, m) {294 if (m->id == id)295 return m;296 }297 298 return NULL;299 }300 301 245 /** Process relocations in modules. 302 246 * … … 316 260 } 317 261 318 void modules_process_tls(rtld_t *rtld)319 {320 #ifdef CONFIG_TLS_VARIANT_1321 list_foreach(rtld->modules, modules_link, module_t, m) {322 m->ioffs = rtld->tls_size;323 list_append(&m->imodules_link, &rtmd->imodules);324 rtld->tls_size += m->tdata_size + m->tbss_size;325 }326 #else /* CONFIG_TLS_VARIANT_2 */327 size_t offs;328 329 list_foreach(rtld->modules, modules_link, module_t, m) {330 rtld->tls_size += m->tdata_size + m->tbss_size;331 }332 333 offs = 0;334 list_foreach(rtld->modules, modules_link, module_t, m) {335 offs += m->tdata_size + m->tbss_size;336 m->ioffs = rtld->tls_size - offs;337 list_append(&m->imodules_link, &rtld->imodules);338 }339 #endif340 }341 342 262 /** Clear BFS tags of all modules. 343 263 */ -
uspace/lib/c/generic/rtld/rtld.c
r0dc2fec raf2254ec 43 43 rtld_t *runtime_env; 44 44 static rtld_t rt_env_static; 45 static module_t prog_mod; 45 46 46 47 /** Initialize the runtime linker for use in a statically-linked executable. */ 47 intrtld_init_static(void)48 void rtld_init_static(void) 48 49 { 49 int rc;50 51 50 runtime_env = &rt_env_static; 52 51 list_initialize(&runtime_env->modules); 53 list_initialize(&runtime_env->imodules);54 52 runtime_env->next_bias = 0x2000000; 55 53 runtime_env->program = NULL; 56 runtime_env->next_id = 1;57 58 rc = module_create_static_exec(runtime_env, NULL);59 if (rc != EOK)60 return rc;61 62 modules_process_tls(runtime_env);63 64 return EOK;65 54 } 66 55 … … 73 62 { 74 63 rtld_t *env; 75 module_t *prog;76 64 77 65 DPRINTF("Load dynamically linked program.\n"); … … 82 70 return ENOMEM; 83 71 84 env->next_id = 1;85 86 prog = calloc(1, sizeof(module_t));87 if (prog == NULL) {88 free(env);89 return ENOMEM;90 }91 92 72 /* 93 73 * First we need to process dynamic sections of the executable … … 96 76 97 77 DPRINTF("Parse program .dynamic section at %p\n", p_info->dynamic); 98 dynamic_parse(p_info->dynamic, 0, &prog->dyn); 99 prog->bias = 0; 100 prog->dyn.soname = "[program]"; 101 prog->rtld = env; 102 prog->id = rtld_get_next_id(env); 103 prog->exec = true; 104 prog->local = false; 105 106 prog->tdata = p_info->tls.tdata; 107 prog->tdata_size = p_info->tls.tdata_size; 108 prog->tbss_size = p_info->tls.tbss_size; 109 prog->tls_align = p_info->tls.tls_align; 110 111 DPRINTF("prog tdata at %p size %zu, tbss size %zu\n", 112 prog->tdata, prog->tdata_size, prog->tbss_size); 78 dynamic_parse(p_info->dynamic, 0, &prog_mod.dyn); 79 prog_mod.bias = 0; 80 prog_mod.dyn.soname = "[program]"; 81 prog_mod.rtld = env; 82 prog_mod.exec = true; 83 prog_mod.local = false; 113 84 114 85 /* Initialize list of loaded modules */ 115 86 list_initialize(&env->modules); 116 list_initialize(&env->imodules); 117 list_append(&prog->modules_link, &env->modules); 87 list_append(&prog_mod.modules_link, &env->modules); 118 88 119 89 /* Pointer to program module. Used as root of the module graph. */ 120 env->program = prog;90 env->program = &prog_mod; 121 91 122 92 /* Work around non-existent memory space allocation. */ … … 128 98 129 99 DPRINTF("Load all program dependencies\n"); 130 module_load_deps(prog, 0); 131 132 /* Compute static TLS size */ 133 modules_process_tls(env); 100 module_load_deps(&prog_mod, 0); 134 101 135 102 /* … … 139 106 /* Process relocations in all modules */ 140 107 DPRINTF("Relocate all modules\n"); 141 modules_process_relocs(env, prog);108 modules_process_relocs(env, &prog_mod); 142 109 143 110 *rre = env; … … 145 112 } 146 113 147 /** Create TLS (Thread Local Storage) data structures.148 *149 * @return Pointer to TCB.150 */151 tcb_t *rtld_tls_make(rtld_t *rtld)152 {153 void *data;154 tcb_t *tcb;155 size_t offset;156 void **dtv;157 size_t nmods;158 size_t i;159 160 tcb = tls_alloc_arch(&data, rtld->tls_size);161 if (tcb == NULL)162 return NULL;163 164 /** Allocate dynamic thread vector */165 nmods = list_count(&rtld->imodules);166 dtv = malloc((nmods + 1) * sizeof(void *));167 if (dtv == NULL) {168 tls_free(tcb);169 return NULL;170 }171 172 /*173 * We define generation number to be equal to vector length.174 * We start with a vector covering the initially loaded modules.175 */176 DTV_GN(dtv) = nmods;177 178 /*179 * Copy thread local data from the initialization images of initial180 * modules. Zero out thread-local uninitialized data.181 */182 183 #ifdef CONFIG_TLS_VARIANT_1184 /*185 * Ascending addresses186 */187 offset = 0; i = 1;188 list_foreach(rtld->imodules, imodules_link, module_t, m) {189 assert(i == m->id);190 assert(offset + m->tdata_size + m->tbss_size <= rtld->tls_size);191 dtv[i++] = data + offset;192 memcpy(data + offset, m->tdata, m->tdata_size);193 offset += m->tdata_size;194 memset(data + offset, 0, m->tbss_size);195 offset += m->tbss_size;196 }197 #else /* CONFIG_TLS_VARIANT_2 */198 /*199 * Descending addresses200 */201 offset = 0; i = 1;202 list_foreach(rtld->imodules, imodules_link, module_t, m) {203 assert(i == m->id);204 assert(offset + m->tdata_size + m->tbss_size <= rtld->tls_size);205 offset += m->tbss_size;206 memset(data + rtld->tls_size - offset, 0, m->tbss_size);207 offset += m->tdata_size;208 memcpy(data + rtld->tls_size - offset, m->tdata, m->tdata_size);209 dtv[i++] = data + rtld->tls_size - offset;210 }211 #endif212 213 tcb->dtv = dtv;214 return tcb;215 }216 217 unsigned long rtld_get_next_id(rtld_t *rtld)218 {219 return rtld->next_id++;220 }221 222 /** Get address of thread-local variable.223 *224 * @param rtld RTLD instance225 * @param tcb TCB of the thread whose instance to return226 * @param mod_id Module ID227 * @param offset Offset within TLS block of the module228 *229 * @return Address of thread-local variable230 */231 void *rtld_tls_get_addr(rtld_t *rtld, tcb_t *tcb, unsigned long mod_id,232 unsigned long offset)233 {234 module_t *m;235 size_t dtv_len;236 void *tls_block;237 238 dtv_len = DTV_GN(tcb->dtv);239 if (dtv_len < mod_id) {240 /* Vector is short */241 242 tcb->dtv = realloc(tcb->dtv, (1 + mod_id) * sizeof(void *));243 /* XXX This can fail if OOM */244 assert(tcb->dtv != NULL);245 /* Zero out new part of vector */246 memset(tcb->dtv + (1 + dtv_len), 0, (mod_id - dtv_len) *247 sizeof(void *));248 }249 250 if (tcb->dtv[mod_id] == NULL) {251 /* TLS block is not allocated */252 253 m = module_by_id(rtld, mod_id);254 assert(m != NULL);255 /* Should not be initial module, those have TLS pre-allocated */256 assert(!link_used(&m->imodules_link));257 258 tls_block = malloc(m->tdata_size + m->tbss_size);259 /* XXX This can fail if OOM */260 assert(tls_block != NULL);261 262 /* Copy tdata */263 memcpy(tls_block, m->tdata, m->tdata_size);264 /* Zero out tbss */265 memset(tls_block + m->tdata_size, 0, m->tbss_size);266 267 tcb->dtv[mod_id] = tls_block;268 }269 270 return (uint8_t *)(tcb->dtv[mod_id]) + offset;271 }272 273 114 /** @} 274 115 */ -
uspace/lib/c/generic/rtld/symbol.c
r0dc2fec raf2254ec 249 249 } 250 250 251 /** Get symbol address. 252 * 253 * @param sym Symbol 254 * @param m Module contaning the symbol 255 * @param tcb TCB of the thread whose thread-local variable instance should 256 * be returned. If @a tcb is @c NULL then @c NULL is returned for 257 * thread-local variables. 258 * 259 * @return Symbol address 260 */ 261 void *symbol_get_addr(elf_symbol_t *sym, module_t *m, tcb_t *tcb) 262 { 263 if (ELF_ST_TYPE(sym->st_info) == STT_TLS) { 264 if (tcb == NULL) 265 return NULL; 266 return rtld_tls_get_addr(m->rtld, tcb, m->id, sym->st_value); 267 } else if (sym->st_shndx == SHN_ABS) { 251 void *symbol_get_addr(elf_symbol_t *sym, module_t *m) 252 { 253 if (sym->st_shndx == SHN_ABS) { 268 254 /* Do not add bias to absolute symbols */ 269 255 return (void *) sym->st_value; -
uspace/lib/c/generic/tls.c
r0dc2fec raf2254ec 34 34 * Support for thread-local storage, as described in: 35 35 * Drepper U.: ELF Handling For Thread-Local Storage, 2005 36 */ 36 * 37 * Only static model is supported. 38 */ 37 39 38 40 #include <tls.h> 39 41 #include <malloc.h> 40 42 #include <str.h> 43 #include <align.h> 41 44 #include <unistd.h> 42 45 43 #ifdef CONFIG_RTLD44 #include <rtld/rtld.h>45 #endif46 47 size_t tls_get_size(void)48 {49 #ifdef CONFIG_RTLD50 if (runtime_env != NULL)51 return runtime_env->tls_size;52 #endif53 return &_tbss_end - &_tdata_start;54 }55 56 /** Get address of static TLS block */57 void *tls_get(void)58 {59 #ifdef CONFIG_TLS_VARIANT_160 return (uint8_t *)__tcb_get() + sizeof(tcb_t);61 #else /* CONFIG_TLS_VARIANT_2 */62 return (uint8_t *)__tcb_get() - tls_get_size();63 #endif64 }65 66 46 /** Create TLS (Thread Local Storage) data structures. 47 * 48 * The code requires, that sections .tdata and .tbss are adjacent. It may be 49 * changed in the future. 67 50 * 68 51 * @return Pointer to TCB. … … 73 56 tcb_t *tcb; 74 57 size_t tls_size = &_tbss_end - &_tdata_start; 75 76 #ifdef CONFIG_RTLD 77 if (runtime_env != NULL) 78 return rtld_tls_make(runtime_env); 79 #endif 58 80 59 tcb = tls_alloc_arch(&data, tls_size); 81 60 if (!tcb) 82 61 return NULL; 83 62 84 63 /* 85 64 * Copy thread local data from the initialization image. … … 97 76 void tls_free(tcb_t *tcb) 98 77 { 99 free(tcb->dtv);100 tls_free_arch(tcb, tls_ get_size());78 size_t tls_size = &_tbss_end - &_tdata_start; 79 tls_free_arch(tcb, tls_size); 101 80 } 102 81 … … 110 89 tcb_t *tls_alloc_variant_1(void **data, size_t size) 111 90 { 112 tcb_t * tcb;91 tcb_t *result; 113 92 114 tcb= malloc(sizeof(tcb_t) + size);115 if (! tcb)93 result = malloc(sizeof(tcb_t) + size); 94 if (!result) 116 95 return NULL; 117 *data = ((void *)tcb) + sizeof(tcb_t); 118 tcb->dtv = NULL; 96 *data = ((void *)result) + sizeof(tcb_t); 119 97 120 return tcb;98 return result; 121 99 } 122 100 … … 143 121 { 144 122 tcb_t *tcb; 145 146 *data = malloc(sizeof(tcb_t) + size); 147 if (*data == NULL) 123 124 size = ALIGN_UP(size, &_tls_alignment); 125 *data = memalign((uintptr_t) &_tls_alignment, sizeof(tcb_t) + size); 126 if (!*data) 148 127 return NULL; 149 128 tcb = (tcb_t *) (*data + size); 150 129 tcb->self = tcb; 151 tcb->dtv = NULL;152 130 153 131 return tcb; … … 161 139 void tls_free_variant_2(tcb_t *tcb, size_t size) 162 140 { 141 size = ALIGN_UP(size, &_tls_alignment); 163 142 void *start = ((void *) tcb) - size; 164 143 free(start); -
uspace/lib/c/include/elf/elf_mod.h
r0dc2fec raf2254ec 58 58 } eld_flags_t; 59 59 60 /** TLS info for a module */61 typedef struct {62 /** tdata section image */63 void *tdata;64 /** Size of tdata section image in bytes */65 size_t tdata_size;66 /** Size of tbss section */67 size_t tbss_size;68 /** Alignment of TLS initialization image */69 size_t tls_align;70 } elf_tls_info_t;71 72 60 /** 73 61 * Some data extracted from the headers are stored here … … 82 70 /** Pointer to the dynamic section */ 83 71 void *dynamic; 84 85 /** TLS info */86 elf_tls_info_t tls;87 72 } elf_finfo_t; 88 73 -
uspace/lib/c/include/rtld/module.h
r0dc2fec raf2254ec 42 42 #include <types/rtld/rtld.h> 43 43 44 extern int module_create_static_exec(rtld_t *, module_t **);45 44 extern void module_process_relocs(module_t *); 46 45 extern module_t *module_find(rtld_t *, const char *); 47 46 extern module_t *module_load(rtld_t *, const char *, mlflags_t); 48 47 extern void module_load_deps(module_t *, mlflags_t); 49 extern module_t *module_by_id(rtld_t *, unsigned long);50 48 51 49 extern void modules_process_relocs(rtld_t *, module_t *); 52 extern void modules_process_tls(rtld_t *);53 50 extern void modules_untag(rtld_t *); 54 51 -
uspace/lib/c/include/rtld/rtld.h
r0dc2fec raf2254ec 41 41 42 42 #include <rtld/dynamic.h> 43 #include <tls.h>44 43 #include <types/rtld/rtld.h> 45 44 46 45 extern rtld_t *runtime_env; 47 46 48 extern intrtld_init_static(void);47 extern void rtld_init_static(void); 49 48 extern int rtld_prog_process(elf_finfo_t *, rtld_t **); 50 extern tcb_t *rtld_tls_make(rtld_t *);51 extern unsigned long rtld_get_next_id(rtld_t *);52 extern void *rtld_tls_get_addr(rtld_t *, tcb_t *, unsigned long, unsigned long);53 49 54 50 #endif -
uspace/lib/c/include/rtld/symbol.h
r0dc2fec raf2254ec 38 38 #include <elf/elf.h> 39 39 #include <rtld/rtld.h> 40 #include <tls.h>41 40 42 41 /** Symbol search flags */ … … 51 50 extern elf_symbol_t *symbol_def_find(const char *, module_t *, 52 51 symbol_search_flags_t, module_t **); 53 extern void *symbol_get_addr(elf_symbol_t *, module_t * , tcb_t *);52 extern void *symbol_get_addr(elf_symbol_t *, module_t *); 54 53 55 54 #endif -
uspace/lib/c/include/tls.h
r0dc2fec raf2254ec 39 39 #include <sys/types.h> 40 40 41 /** DTV Generation number - equals vector length */42 #define DTV_GN(dtv) (((uintptr_t *)(dtv))[0])43 44 41 /* 45 42 * Symbols defined in the respective linker script. … … 55 52 extern void tls_free(tcb_t *); 56 53 extern void tls_free_arch(tcb_t *, size_t); 57 extern size_t tls_get_size(void);58 extern void *tls_get(void);59 54 60 55 #ifdef CONFIG_TLS_VARIANT_1 -
uspace/lib/c/include/types/rtld/module.h
r0dc2fec raf2254ec 46 46 /** Dynamically linked module */ 47 47 typedef struct module { 48 /** Module ID */49 unsigned long id;50 /** Dynamic info for this module */51 48 dyn_info_t dyn; 52 /** Load bias */53 49 size_t bias; 54 55 /** tdata image start */56 void *tdata;57 /** tdata image size */58 size_t tdata_size;59 /** tbss size */60 size_t tbss_size;61 /** TLS alignment */62 size_t tls_align;63 64 size_t ioffs;65 50 66 51 /** Containing rtld */ … … 76 61 /** Link to list of all modules in runtime environment */ 77 62 link_t modules_link; 78 /** Link to list of initial modules */79 link_t imodules_link;80 63 81 64 /** Link to BFS queue. Only used when doing a BFS of the module graph */ -
uspace/lib/c/include/types/rtld/rtld.h
r0dc2fec raf2254ec 48 48 module_t *program; 49 49 50 /** Next module ID */51 unsigned long next_id;52 53 /** Size of initial TLS tdata + tbss */54 size_t tls_size;55 56 50 /** List of all loaded modules including rtld and the program */ 57 51 list_t modules; 58 59 /** List of initial modules */60 list_t imodules;61 52 62 53 /** Temporary hack to place each module at different address. */ -
uspace/lib/dltest/dltest.c
r0dc2fec raf2254ec 34 34 */ 35 35 36 #include <fibril.h>37 36 #include "libdltest.h" 38 37 … … 46 45 /** Public uninitialized variable */ 47 46 int dl_public_uvar; 48 49 /** Private initialized fibril-local variable */50 static fibril_local int dl_private_fib_var = dl_private_fib_var_val;51 /** Private uninitialized fibril-local variable */52 static fibril_local int dl_private_fib_uvar;53 54 /** Public initialized fibril-local variable */55 fibril_local int dl_public_fib_var = dl_public_fib_var_val;56 /** Public uninitialized fibril-local variable */57 fibril_local int dl_public_fib_uvar;58 47 59 48 /** Return constant value. */ … … 69 58 } 70 59 71 /** Return address of private initialized variable */72 int *dl_get_private_var_addr(void)73 {74 return &private_var;75 }76 77 60 /** Return value of private uninitialized variable */ 78 61 int dl_get_private_uvar(void) 79 62 { 80 63 return private_uvar; 81 }82 83 /** Return vaddress of private uninitialized variable */84 int *dl_get_private_uvar_addr(void)85 {86 return &private_uvar;87 64 } 88 65 … … 93 70 } 94 71 95 /** Return address of public initialized variable */96 int *dl_get_public_var_addr(void)97 {98 return &dl_public_var;99 }100 101 72 /** Return value of public uninitialized variable */ 102 73 int dl_get_public_uvar(void) … … 105 76 } 106 77 107 /** Return address of public uninitialized variable */108 int *dl_get_public_uvar_addr(void)109 {110 return &dl_public_uvar;111 }112 113 /** Return value of private initialized fibril-local variable */114 int dl_get_private_fib_var(void)115 {116 return dl_private_fib_var;117 }118 119 /** Return address of private initialized fibril-local variable */120 int *dl_get_private_fib_var_addr(void)121 {122 return &dl_private_fib_var;123 }124 125 /** Return value of private uninitialized fibril-local variable */126 int dl_get_private_fib_uvar(void)127 {128 return dl_private_fib_uvar;129 }130 131 /** Return address of private uninitialized fibril-local variable */132 int *dl_get_private_fib_uvar_addr(void)133 {134 return &dl_private_fib_uvar;135 }136 137 /** Return value of public initialized fibril-local variable */138 int dl_get_public_fib_var(void)139 {140 return dl_public_fib_var;141 }142 143 /** Return value of public initialized fibril-local variable */144 int *dl_get_public_fib_var_addr(void)145 {146 return &dl_public_fib_var;147 }148 149 /** Return value of public uninitialized fibril-local variable */150 int dl_get_public_fib_uvar(void)151 {152 return dl_public_fib_uvar;153 }154 155 /** Return value of public uninitialized fibril-local variable */156 int *dl_get_public_fib_uvar_addr(void)157 {158 return &dl_public_fib_uvar;159 }160 161 78 /** 162 79 * @} -
uspace/lib/dltest/libdltest.h
r0dc2fec raf2254ec 37 37 #define LIBDLTEST_H 38 38 39 #include <fibril.h>40 41 39 enum { 42 40 dl_constant = 110011, 43 41 dl_private_var_val = 220022, 44 dl_public_var_val = 330033, 45 dl_private_fib_var_val = 440044, 46 dl_public_fib_var_val = 550055 42 dl_public_var_val = 330033 47 43 }; 48 44 49 45 extern int dl_get_constant(void); 50 46 extern int dl_get_private_var(void); 51 extern int *dl_get_private_var_addr(void);52 47 extern int dl_get_private_uvar(void); 53 extern int *dl_get_private_uvar_addr(void);54 48 extern int dl_get_public_var(void); 55 extern int *dl_get_public_var_addr(void);56 49 extern int dl_get_public_uvar(void); 57 extern int *dl_get_public_uvar_addr(void);58 extern int dl_get_private_fib_var(void);59 extern int *dl_get_private_fib_var_addr(void);60 extern int dl_get_private_fib_uvar(void);61 extern int *dl_get_private_fib_uvar_addr(void);62 extern int dl_get_public_fib_var(void);63 extern int *dl_get_public_fib_var_addr(void);64 extern int dl_get_public_fib_uvar(void);65 extern int *dl_get_public_fib_uvar_addr(void);66 50 67 51 extern int dl_public_var; 68 52 extern int dl_public_uvar; 69 extern fibril_local int dl_public_fib_var;70 extern fibril_local int dl_public_fib_uvar;71 53 72 54 #endif -
uspace/srv/loader/main.c
r0dc2fec raf2254ec 269 269 270 270 pcb.filc = filc; 271 printf("dynamic=%p rtld_env=%p\n", pcb.dynamic, pcb.rtld_runtime); 271 272 272 273 async_answer_0(rid, rc);
Note:
See TracChangeset
for help on using the changeset viewer.