Changes in / [0dc2fec:af2254ec] in mainline


Ignore:
Files:
2 deleted
30 edited

Legend:

Unmodified
Added
Removed
  • .bzrignore

    r0dc2fec raf2254ec  
    3535uspace/app/devctl/devctl
    3636uspace/app/dltest/dltest
    37 uspace/app/dltests/dltests
    3837uspace/app/dnscfg/dnscfg
    3938uspace/app/dnsres/dnsres
     
    9796uspace/dist/app/devctl
    9897uspace/dist/app/dltest
    99 uspace/dist/app/dltests
    10098uspace/dist/app/dnscfg
    10199uspace/dist/app/dnsres
  • abi/include/abi/elf.h

    r0dc2fec raf2254ec  
    157157#define STT_SECTION  3
    158158#define STT_FILE     4
    159 #define STT_TLS      6
    160159#define STT_LOPROC   13
    161160#define STT_HIPROC   15
     
    171170#define PT_SHLIB    5
    172171#define PT_PHDR     6
    173 #define PT_TLS      7
    174172#define PT_LOPROC   0x70000000
    175173#define PT_HIPROC   0x7fffffff
  • boot/Makefile.common

    r0dc2fec raf2254ec  
    226226ifeq ($(CONFIG_BUILD_SHARED_LIBS), y)
    227227        RD_APPS_NON_ESSENTIAL += \
    228                 $(USPACE_PATH)/app/dltest/dltest \
    229                 $(USPACE_PATH)/app/dltests/dltests
     228                $(USPACE_PATH)/app/dltest/dltest
    230229endif
    231230
  • kernel/generic/src/lib/elf.c

    r0dc2fec raf2254ec  
    163163        case PT_LOAD:
    164164                return load_segment(entry, elf, as);
    165         case PT_TLS:
    166                 break;
    167165        case PT_DYNAMIC:
    168166        case PT_INTERP:
  • uspace/Makefile

    r0dc2fec raf2254ec  
    4141        app/corecfg \
    4242        app/devctl \
     43        app/dltest \
    4344        app/dnscfg \
    4445        app/dnsres \
     
    166167        drv/platform/icp
    167168
    168 
    169169## Platform-specific hardware support
    170170#
     
    210210                drv/fb/amdm37x_dispc \
    211211                srv/hw/irc/icp-ic
    212 endif
    213 
    214 ## Dynamic linking tests
    215 #
    216 ifeq ($(CONFIG_BUILD_SHARED_LIBS),y)
    217         DIRS += \
    218                 app/dltest \
    219                 app/dltests
    220212endif
    221213
  • uspace/Makefile.common

    r0dc2fec raf2254ec  
    191191ifeq ($(STATIC_BUILD),y)
    192192        BASE_LIBS = $(LIBC_PREFIX)/libc.a $(LIBSOFTINT_PREFIX)/libsoftint.a
     193        LINKER_SCRIPT ?= $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld
    193194        ifeq ($(MATH),y)
    194195                BASE_LIBS += $(LIBMATH_PREFIX)/libmath.a
     
    196197else
    197198        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
    199201        ifeq ($(MATH),y)
    200202                BASE_LIBS += $(LIBMATH_PREFIX)/libmath.so.0
    201203        endif
    202 endif
    203 
    204 ifeq ($(LINK_DYNAMIC),y)
    205         LFLAGS += -Bdynamic
    206         LINKER_SCRIPT ?= $(LIBC_PREFIX)/arch/$(UARCH)/_link-dlexe.ld
    207 else
    208         LINKER_SCRIPT ?= $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld
    209204endif
    210205
  • uspace/app/dltest/Makefile

    r0dc2fec raf2254ec  
    2828
    2929USPACE_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 
     30EXTRA_CFLAGS = -I$(LIBDLTEST_PREFIX)
    3531BINARY = dltest
    3632
  • uspace/app/dltest/dltest.c

    r0dc2fec raf2254ec  
    4343
    4444/** libdltest library handle */
    45 static void *handle;
    46 
    47 /** If true, do not run dlfcn tests */
    48 static bool no_dlfcn = false;
     45void *handle;
    4946
    5047/** Test dlsym() function */
     
    9693{
    9794        int (*p_dl_get_private_var)(void);
    98         int *(*p_dl_get_private_var_addr)(void);
    9995        int val;
    10096
     
    107103        }
    108104
    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 
    115105        val = p_dl_get_private_var();
    116106
    117107        printf("Got %d, expected %d... ", val, dl_private_var_val);
    118108        if (val != dl_private_var_val) {
    119                 printf("dl_get_private_var_addr -> %p\n",
    120                     p_dl_get_private_var_addr());
    121109                printf("FAILED\n");
    122110                return false;
     
    133121{
    134122        int (*p_dl_get_private_uvar)(void);
    135         int *(*p_dl_get_private_uvar_addr)(void);
    136123        int val;
    137124
     
    144131        }
    145132
    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 
    152133        val = p_dl_get_private_uvar();
    153134
    154135        printf("Got %d, expected %d... ", val, 0);
    155136        if (val != 0) {
    156                 printf("dl_get_private_uvar_addr -> %p\n",
    157                     p_dl_get_private_uvar_addr());
    158137                printf("FAILED\n");
    159138                return false;
     
    170149{
    171150        int (*p_dl_get_public_var)(void);
    172         int *(*p_dl_get_public_var_addr)(void);
    173151        int val;
    174152
     
    181159        }
    182160
    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 
    189161        val = p_dl_get_public_var();
    190162
    191163        printf("Got %d, expected %d... ", val, dl_public_var_val);
    192164        if (val != dl_public_var_val) {
    193                 printf("dl_get_public_var_addr -> %p\n",
    194                     p_dl_get_public_var_addr());
    195165                printf("FAILED\n");
    196166                return false;
     
    207177{
    208178        int (*p_dl_get_public_uvar)(void);
    209         int *(*p_dl_get_public_uvar_addr)(void);
    210179        int val;
    211180
     
    218187        }
    219188
    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 
    226189        val = p_dl_get_public_uvar();
    227190
    228191        printf("Got %d, expected %d... ", val, 0);
    229192        if (val != 0) {
    230                 printf("dl_get_public_uvar_addr -> %p\n",
    231                     p_dl_get_public_uvar_addr());
    232193                printf("FAILED\n");
    233194                return false;
     
    244205{
    245206        int *p_dl_public_var;
    246         int *(*p_dl_get_public_var_addr)(void);
    247207        int val;
    248208
     
    255215        }
    256216
    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 
    263217        val = *p_dl_public_var;
    264218
    265219        printf("Got %d, expected %d... ", val, dl_public_var_val);
    266220        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());
    270221                printf("FAILED\n");
    271222                return false;
     
    282233{
    283234        int *p_dl_public_uvar;
    284         int *(*p_dl_get_public_uvar_addr)(void);
    285235        int val;
    286236
     
    293243        }
    294244
    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 
    301245        val = *p_dl_public_uvar;
    302246
    303247        printf("Got %d, expected %d... ", val, 0);
    304248        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
     257int main(int argc, char *argv[])
     258{
     259
     260        printf("Dynamic linking test\n");
     261
    839262        printf("dlopen()... ");
    840263        handle = dlopen("libdltest.so.0", 0);
     
    870293                return 1;
    871294
    872 #ifndef STATIC_EXE
    873         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 
    892295//      printf("dlclose()... ");
    893296//      dlclose(handle);
    894297//      printf("Passed\n");
    895298
    896         return 0;
    897 }
    898 
    899 #ifdef DLTEST_LINKED
    900 
    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_LINKED
    977         if (test_lnk() != 0)
    978                 return 1;
    979 #endif
    980 
    981299        printf("All passed.\n");
    982300        return 0;
  • uspace/lib/c/arch/ia32/_link.ld.in

    r0dc2fec raf2254ec  
    1212#endif
    1313        data PT_LOAD FLAGS(6);
    14         tls PT_TLS;
    1514#if defined(SHLIB) || defined(DLEXE)
    1615        dynamic PT_DYNAMIC;
     
    9695#endif
    9796       
     97#ifndef DLEXE
    9898        .tdata : {
    99 #ifndef DLEXE
    10099                _tdata_start = .;
    101 #endif
    102100                *(.tdata);
    103101                *(.gnu.linkonce.tb.*);
    104 #ifndef DLEXE
    105102                _tdata_end = .;
    106 #endif
    107         } :data :tls
    108         .tbss : {
    109 #ifndef DLEXE
    110103                _tbss_start = .;
    111 #endif
    112104                *(.tbss);
    113 #ifndef DLEXE
    114105                _tbss_end = .;
    115 #endif
    116         } :data :tls
     106        } :data
    117107       
    118 #ifndef DLEXE
    119108        _tls_alignment = ALIGNOF(.tdata);
    120109#endif
  • uspace/lib/c/arch/ia32/include/libarch/rtld/elf_dyn.h

    r0dc2fec raf2254ec  
    3636#define LIBC_ia32_RTLD_ELF_DYN_H_
    3737
    38 /*
     38/* 
    3939 * ia32 dynamic relocation types
    4040 */
     
    4747#define R_386_RELATIVE  8
    4848
    49 #define R_386_TLS_TPOFF    14
    5049#define R_386_TLS_DTPMOD32 35
    51 #define R_386_TLS_DTPOFF32 36
    5250
    5351#endif
  • uspace/lib/c/arch/ia32/include/libarch/tls.h

    r0dc2fec raf2254ec  
    4343        void *self;
    4444        void *fibril_data;
    45         void **dtv;
    4645} tcb_t;
    4746
  • uspace/lib/c/arch/ia32/src/rtld/reloc.c

    r0dc2fec raf2254ec  
    101101                        sym_def = symbol_def_find(str_tab + sym->st_name,
    102102                            m, ssf_none, &dest);
    103                         DPRINTF("dest name: '%s'\n", dest->dyn.soname);
     103//                      DPRINTF("dest name: '%s'\n", dest->dyn.soname);
    104104//                      DPRINTF("dest bias: 0x%x\n", dest->bias);
    105105                        if (sym_def) {
    106106                                sym_addr = (uint32_t)
    107                                     symbol_get_addr(sym_def, dest, NULL);
     107                                    symbol_get_addr(sym_def, dest);
    108108//                              DPRINTF("symbol definition found, addr=0x%x\n", sym_addr);
    109109                        } else {
     
    115115                        sym_addr = 0;
    116116                        sym_def = NULL;
    117 
    118                         /*
    119                          * DTPMOD with null st_name should return the index
    120                          * of the current module.
    121                          */
    122                         dest = m;
    123117                }
    124118
     
    154148                        if (sym_def) {
    155149                                sym_addr = (uint32_t)
    156                                     symbol_get_addr(sym_def, dest, NULL);
     150                                    symbol_get_addr(sym_def, dest);
    157151                        } else {
    158152                                printf("Source definition of '%s' not found.\n",
     
    177171                        break;
    178172
    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 
    189173                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");
    192179                        break;
    193180
  • uspace/lib/c/arch/ia32/src/tls.c

    r0dc2fec raf2254ec  
    11/*
    22 * Copyright (c) 2006 Ondrej Palkovsky
    3  * Copyright (c) 2016 Jiri Svoboda
    43 * All rights reserved.
    54 *
     
    4039#include <align.h>
    4140
    42 #ifdef CONFIG_RTLD
    43 #include <rtld/rtld.h>
    44 #endif
    45 
    4641tcb_t *tls_alloc_arch(void **data, size_t size)
    4742{
     
    6964    *___tls_get_addr(tls_index *ti)
    7065{
     66        size_t tls_size;
    7167        uint8_t *tls;
    7268
    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
    8175        return tls + ti->ti_offset;
    8276}
  • uspace/lib/c/generic/dlfcn.c

    r0dc2fec raf2254ec  
    4949        module_t *m;
    5050
     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);
    5159        m = module_find(runtime_env, path);
    5260        if (m == NULL) {
     61                printf("NULL. module_load('%s')\n", path);
    5362                m = module_load(runtime_env, path, mlf_local);
     63                printf("module_load_deps(m)\n");
    5464                module_load_deps(m, mlf_local);
    5565                /* Now relocate. */
     66                printf("module_process_relocs(m)\n");
    5667                module_process_relocs(m);
     68        } else {
     69                printf("not NULL\n");
    5770        }
    5871
     
    6881        module_t *sm;
    6982
     83        printf("dlsym(0x%lx, \"%s\")\n", (long)mod, sym_name);
    7084        sd = symbol_bfs_find(sym_name, (module_t *) mod, &sm);
    7185        if (sd != NULL) {
    72                 return symbol_get_addr(sd, sm, __tcb_get());
     86                return symbol_get_addr(sd, sm);
    7387        }
    7488
  • uspace/lib/c/generic/elf/elf_mod.c

    r0dc2fec raf2254ec  
    248248}
    249249
    250 /** Process TLS program header.
    251  *
    252  * @param elf  Pointer to loader state buffer.
    253  * @param hdr  TLS program header
    254  * @param info Place to store TLS info
    255  */
    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 
    265250/** Process segment header.
    266251 *
    267  * @param elf   Pointer to loader state buffer.
    268252 * @param entry Segment header.
    269253 *
     
    293277        case 0x70000000:
    294278                /* 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));
    301279                break;
    302280        case PT_SHLIB:
  • uspace/lib/c/generic/libc.c

    r0dc2fec raf2254ec  
    4141 */
    4242
    43 #include <errno.h>
    4443#include <libc.h>
    4544#include <stdlib.h>
     
    6968        __malloc_init();
    7069       
    71         /* Save the PCB pointer */
    72         __pcb = (pcb_t *) pcb_ptr;
    73        
    74 #ifdef CONFIG_RTLD
    75         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 #endif
    82        
    8370        fibril_t *fibril = fibril_setup();
    8471        if (fibril == NULL)
     
    8774        __tcb_set(fibril->tcb);
    8875       
     76        /* Save the PCB pointer */
     77        __pcb = (pcb_t *) pcb_ptr;
    8978       
    9079#ifdef FUTEX_UPGRADABLE
     
    10089        char **argv;
    10190       
     91#ifdef CONFIG_RTLD
     92        if (__pcb != NULL && __pcb->rtld_runtime != NULL) {
     93                runtime_env = (rtld_t *) __pcb->rtld_runtime;
     94        }
     95#endif
    10296        /*
    10397         * Get command line arguments and initialize
  • uspace/lib/c/generic/rtld/module.c

    r0dc2fec raf2254ec  
    3737#include <adt/list.h>
    3838#include <elf/elf_load.h>
    39 #include <errno.h>
    4039#include <fcntl.h>
    4140#include <loader/pcb.h>
     
    4948#include <rtld/rtld_arch.h>
    5049#include <rtld/module.h>
    51 
    52 /** Create module for static executable.
    53  *
    54  * @param rtld Run-time dynamic linker
    55  * @param rmodule Place to store pointer to new module or @c NULL
    56  * @return EOK on success, ENOMEM if out of memory
    57  */
    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 }
    8450
    8551/** (Eagerly) process all relocation tables in a module.
     
    169135
    170136        m = calloc(1, sizeof(module_t));
    171         if (m == NULL) {
     137        if (!m) {
    172138                printf("malloc failed\n");
    173139                exit(1);
     
    175141
    176142        m->rtld = rtld;
    177         m->id = rtld_get_next_id(rtld);
    178 
    179143        if ((flags & mlf_local) != 0)
    180144                m->local = true;
     
    217181        /* Insert into the list of loaded modules */
    218182        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);
    228183
    229184        return m;
     
    288243}
    289244
    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 
    301245/** Process relocations in modules.
    302246 *
     
    316260}
    317261
    318 void modules_process_tls(rtld_t *rtld)
    319 {
    320 #ifdef CONFIG_TLS_VARIANT_1
    321         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 #endif
    340 }
    341 
    342262/** Clear BFS tags of all modules.
    343263 */
  • uspace/lib/c/generic/rtld/rtld.c

    r0dc2fec raf2254ec  
    4343rtld_t *runtime_env;
    4444static rtld_t rt_env_static;
     45static module_t prog_mod;
    4546
    4647/** Initialize the runtime linker for use in a statically-linked executable. */
    47 int rtld_init_static(void)
     48void rtld_init_static(void)
    4849{
    49         int rc;
    50 
    5150        runtime_env = &rt_env_static;
    5251        list_initialize(&runtime_env->modules);
    53         list_initialize(&runtime_env->imodules);
    5452        runtime_env->next_bias = 0x2000000;
    5553        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;
    6554}
    6655
     
    7362{
    7463        rtld_t *env;
    75         module_t *prog;
    7664
    7765        DPRINTF("Load dynamically linked program.\n");
     
    8270                return ENOMEM;
    8371
    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 
    9272        /*
    9373         * First we need to process dynamic sections of the executable
     
    9676
    9777        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;
    11384
    11485        /* Initialize list of loaded modules */
    11586        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);
    11888
    11989        /* Pointer to program module. Used as root of the module graph. */
    120         env->program = prog;
     90        env->program = &prog_mod;
    12191
    12292        /* Work around non-existent memory space allocation. */
     
    12898
    12999        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);
    134101
    135102        /*
     
    139106        /* Process relocations in all modules */
    140107        DPRINTF("Relocate all modules\n");
    141         modules_process_relocs(env, prog);
     108        modules_process_relocs(env, &prog_mod);
    142109
    143110        *rre = env;
     
    145112}
    146113
    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 initial
    180          * modules. Zero out thread-local uninitialized data.
    181          */
    182 
    183 #ifdef CONFIG_TLS_VARIANT_1
    184         /*
    185          * Ascending addresses
    186          */
    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 addresses
    200          */
    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 #endif
    212 
    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 instance
    225  * @param tcb TCB of the thread whose instance to return
    226  * @param mod_id Module ID
    227  * @param offset Offset within TLS block of the module
    228  *
    229  * @return Address of thread-local variable
    230  */
    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 
    273114/** @}
    274115 */
  • uspace/lib/c/generic/rtld/symbol.c

    r0dc2fec raf2254ec  
    249249}
    250250
    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) {
     251void *symbol_get_addr(elf_symbol_t *sym, module_t *m)
     252{
     253        if (sym->st_shndx == SHN_ABS) {
    268254                /* Do not add bias to absolute symbols */
    269255                return (void *) sym->st_value;
  • uspace/lib/c/generic/tls.c

    r0dc2fec raf2254ec  
    3434 * Support for thread-local storage, as described in:
    3535 *      Drepper U.: ELF Handling For Thread-Local Storage, 2005
    36  */
     36 *
     37 * Only static model is supported.
     38 */
    3739
    3840#include <tls.h>
    3941#include <malloc.h>
    4042#include <str.h>
     43#include <align.h>
    4144#include <unistd.h>
    4245
    43 #ifdef CONFIG_RTLD
    44 #include <rtld/rtld.h>
    45 #endif
    46 
    47 size_t tls_get_size(void)
    48 {
    49 #ifdef CONFIG_RTLD
    50         if (runtime_env != NULL)
    51                 return runtime_env->tls_size;
    52 #endif
    53         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_1
    60         return (uint8_t *)__tcb_get() + sizeof(tcb_t);
    61 #else /* CONFIG_TLS_VARIANT_2 */
    62         return (uint8_t *)__tcb_get() - tls_get_size();
    63 #endif
    64 }
    65 
    6646/** 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.
    6750 *
    6851 * @return Pointer to TCB.
     
    7356        tcb_t *tcb;
    7457        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       
    8059        tcb = tls_alloc_arch(&data, tls_size);
    8160        if (!tcb)
    8261                return NULL;
    83 
     62       
    8463        /*
    8564         * Copy thread local data from the initialization image.
     
    9776void tls_free(tcb_t *tcb)
    9877{
    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);
    10180}
    10281
     
    11089tcb_t *tls_alloc_variant_1(void **data, size_t size)
    11190{
    112         tcb_t *tcb;
     91        tcb_t *result;
    11392
    114         tcb = malloc(sizeof(tcb_t) + size);
    115         if (!tcb)
     93        result = malloc(sizeof(tcb_t) + size);
     94        if (!result)
    11695                return NULL;
    117         *data = ((void *)tcb) + sizeof(tcb_t);
    118         tcb->dtv = NULL;
     96        *data = ((void *)result) + sizeof(tcb_t);
    11997
    120         return tcb;
     98        return result;
    12199}
    122100
     
    143121{
    144122        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)
    148127                return NULL;
    149128        tcb = (tcb_t *) (*data + size);
    150129        tcb->self = tcb;
    151         tcb->dtv = NULL;
    152130
    153131        return tcb;
     
    161139void tls_free_variant_2(tcb_t *tcb, size_t size)
    162140{
     141        size = ALIGN_UP(size, &_tls_alignment);
    163142        void *start = ((void *) tcb) - size;
    164143        free(start);
  • uspace/lib/c/include/elf/elf_mod.h

    r0dc2fec raf2254ec  
    5858} eld_flags_t;
    5959
    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 
    7260/**
    7361 * Some data extracted from the headers are stored here
     
    8270        /** Pointer to the dynamic section */
    8371        void *dynamic;
    84 
    85         /** TLS info */
    86         elf_tls_info_t tls;
    8772} elf_finfo_t;
    8873
  • uspace/lib/c/include/rtld/module.h

    r0dc2fec raf2254ec  
    4242#include <types/rtld/rtld.h>
    4343
    44 extern int module_create_static_exec(rtld_t *, module_t **);
    4544extern void module_process_relocs(module_t *);
    4645extern module_t *module_find(rtld_t *, const char *);
    4746extern module_t *module_load(rtld_t *, const char *, mlflags_t);
    4847extern void module_load_deps(module_t *, mlflags_t);
    49 extern module_t *module_by_id(rtld_t *, unsigned long);
    5048
    5149extern void modules_process_relocs(rtld_t *, module_t *);
    52 extern void modules_process_tls(rtld_t *);
    5350extern void modules_untag(rtld_t *);
    5451
  • uspace/lib/c/include/rtld/rtld.h

    r0dc2fec raf2254ec  
    4141
    4242#include <rtld/dynamic.h>
    43 #include <tls.h>
    4443#include <types/rtld/rtld.h>
    4544
    4645extern rtld_t *runtime_env;
    4746
    48 extern int rtld_init_static(void);
     47extern void rtld_init_static(void);
    4948extern 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);
    5349
    5450#endif
  • uspace/lib/c/include/rtld/symbol.h

    r0dc2fec raf2254ec  
    3838#include <elf/elf.h>
    3939#include <rtld/rtld.h>
    40 #include <tls.h>
    4140
    4241/** Symbol search flags */
     
    5150extern elf_symbol_t *symbol_def_find(const char *, module_t *,
    5251    symbol_search_flags_t, module_t **);
    53 extern void *symbol_get_addr(elf_symbol_t *, module_t *, tcb_t *);
     52extern void *symbol_get_addr(elf_symbol_t *, module_t *);
    5453
    5554#endif
  • uspace/lib/c/include/tls.h

    r0dc2fec raf2254ec  
    3939#include <sys/types.h>
    4040
    41 /** DTV Generation number - equals vector length */
    42 #define DTV_GN(dtv) (((uintptr_t *)(dtv))[0])
    43 
    4441/*
    4542 * Symbols defined in the respective linker script.
     
    5552extern void tls_free(tcb_t *);
    5653extern void tls_free_arch(tcb_t *, size_t);
    57 extern size_t tls_get_size(void);
    58 extern void *tls_get(void);
    5954
    6055#ifdef CONFIG_TLS_VARIANT_1
  • uspace/lib/c/include/types/rtld/module.h

    r0dc2fec raf2254ec  
    4646/** Dynamically linked module */
    4747typedef struct module {
    48         /** Module ID */
    49         unsigned long id;
    50         /** Dynamic info for this module */
    5148        dyn_info_t dyn;
    52         /** Load bias */
    5349        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;
    6550
    6651        /** Containing rtld */
     
    7661        /** Link to list of all modules in runtime environment */
    7762        link_t modules_link;
    78         /** Link to list of initial modules */
    79         link_t imodules_link;
    8063
    8164        /** Link to BFS queue. Only used when doing a BFS of the module graph */
  • uspace/lib/c/include/types/rtld/rtld.h

    r0dc2fec raf2254ec  
    4848        module_t *program;
    4949
    50         /** Next module ID */
    51         unsigned long next_id;
    52 
    53         /** Size of initial TLS tdata + tbss */
    54         size_t tls_size;
    55 
    5650        /** List of all loaded modules including rtld and the program */
    5751        list_t modules;
    58 
    59         /** List of initial modules */
    60         list_t imodules;
    6152
    6253        /** Temporary hack to place each module at different address. */
  • uspace/lib/dltest/dltest.c

    r0dc2fec raf2254ec  
    3434 */
    3535
    36 #include <fibril.h>
    3736#include "libdltest.h"
    3837
     
    4645/** Public uninitialized variable */
    4746int 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;
    5847
    5948/** Return constant value. */
     
    6958}
    7059
    71 /** Return address of private initialized variable */
    72 int *dl_get_private_var_addr(void)
    73 {
    74         return &private_var;
    75 }
    76 
    7760/** Return value of private uninitialized variable */
    7861int dl_get_private_uvar(void)
    7962{
    8063        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;
    8764}
    8865
     
    9370}
    9471
    95 /** Return address of public initialized variable */
    96 int *dl_get_public_var_addr(void)
    97 {
    98         return &dl_public_var;
    99 }
    100 
    10172/** Return value of public uninitialized variable */
    10273int dl_get_public_uvar(void)
     
    10576}
    10677
    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 
    16178/**
    16279 * @}
  • uspace/lib/dltest/libdltest.h

    r0dc2fec raf2254ec  
    3737#define LIBDLTEST_H
    3838
    39 #include <fibril.h>
    40 
    4139enum {
    4240        dl_constant = 110011,
    4341        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
    4743};
    4844
    4945extern int dl_get_constant(void);
    5046extern int dl_get_private_var(void);
    51 extern int *dl_get_private_var_addr(void);
    5247extern int dl_get_private_uvar(void);
    53 extern int *dl_get_private_uvar_addr(void);
    5448extern int dl_get_public_var(void);
    55 extern int *dl_get_public_var_addr(void);
    5649extern 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);
    6650
    6751extern int dl_public_var;
    6852extern int dl_public_uvar;
    69 extern fibril_local int dl_public_fib_var;
    70 extern fibril_local int dl_public_fib_uvar;
    7153
    7254#endif
  • uspace/srv/loader/main.c

    r0dc2fec raf2254ec  
    269269       
    270270        pcb.filc = filc;
     271        printf("dynamic=%p rtld_env=%p\n", pcb.dynamic, pcb.rtld_runtime);
    271272       
    272273        async_answer_0(rid, rc);
Note: See TracChangeset for help on using the changeset viewer.