diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | elf/Makefile | 2 | ||||
-rw-r--r-- | elf/rtld.c | 3 | ||||
-rw-r--r-- | elf/tst-tls1.c | 81 | ||||
-rw-r--r-- | sysdeps/generic/dl-tls.c | 18 |
5 files changed, 100 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog index e131c96a07..0d21e736e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,16 @@ 2002-02-09 Ulrich Drepper <drepper@redhat.com> + * elf/Makefile (tests): Add tst-tls1. + * elf/tst-tls1.c: New file. + + * sysdeps/generic/dl-tls.c (_dl_determine_tlsoffset): Don't handle + alignment of TCB for now. + + * elf/rtld.c (dl_main): Use p_vaddr as address of TLS + initialization image for the application itself. + * sysdeps/generic/dl-tls.c (_dl_allocate_tls): Correctly terminate - loop to initial TLS block. + loop to initialize TLS block. 2002-02-08 Richard Henderson <rth@twiddle.net> diff --git a/elf/Makefile b/elf/Makefile index 476341902d..4235a594e8 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -117,7 +117,7 @@ tests = loadtest restest1 preloadtest loadfail multiload origtest resolvfail \ reldep reldep2 reldep3 reldep4 $(tests-nodelete-$(have-z-nodelete)) \ $(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \ neededtest3 neededtest4 unload2 lateglobal initfirst global \ - restest2 next dblload dblunload reldep5 reldep6 + restest2 next dblload dblunload reldep5 reldep6 tst-tls1 test-srcs = tst-pathopt tests-vis-yes = vismain tests-nodelete-yes = nodelete diff --git a/elf/rtld.c b/elf/rtld.c index 2ebde4530a..f87462eda8 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -730,8 +730,7 @@ of this helper program; chances are you did not intend to run this program.\n\ GL(dl_loaded)->l_tls_blocksize = ph->p_memsz; GL(dl_loaded)->l_tls_align = ph->p_align; GL(dl_loaded)->l_tls_initimage_size = ph->p_filesz; - GL(dl_loaded)->l_tls_initimage = (void *) (GL(dl_loaded)->l_addr - + ph->p_offset); + GL(dl_loaded)->l_tls_initimage = (void *) ph->p_vaddr; /* This is the first element of the initialization image list. We create the list as circular since we have to append at the end. */ diff --git a/elf/tst-tls1.c b/elf/tst-tls1.c new file mode 100644 index 0000000000..4d0913890c --- /dev/null +++ b/elf/tst-tls1.c @@ -0,0 +1,81 @@ +/* glibc test for TLS in ld.so. */ +#include <stdio.h> + +#include <tls.h> + + +/* XXX Until gcc gets told how to define and use thread-local + variables we will have to resort to use asms. */ +//asm (".tls_common foo,4,4"); +asm (".section \".tdata\", \"awT\", @progbits\n\t" + ".align 4\n\t" + ".globl foo\n" + "foo:\t.long 0\n\t" + ".globl bar\n" + "bar:\t.long 0\n\t" + ".previous"); + + +int +main (void) +{ +#ifdef USE_TLS + int result = 0; + int a, b; + + /* XXX Each architecture must have its own asm for now. */ +# ifdef __i386__ + /* Set the variable using the local exec model. */ + puts ("set bar to 1 (LE)"); + asm ("movl %gs:0,%eax\n\t" + "subl $bar@tpoff,%eax\n\t" + "movl $1,(%eax)"); + +#if 0 + // XXX Doesn't work yet; no runtime relocations. + fputs ("get sum of foo and bar (IE)", stdout); + asm ("call 1f\n\t" + ".subsection 1\n" + "1:\tmovl (%%esp), %%ebx\n\t" + "ret\n\t" + ".previous\n\t" + "addl $_GLOBAL_OFFSET_TABLE_, %%ebx\n\t" + "movl %%gs:0,%%eax\n\t" + "movl %%eax,%%edx\n\t" + "addl foo@gottpoff(%%ebx),%%eax\n\t" + "addl bar@gottpoff(%%ebx),%%eax\n\t" + "movl (%%eax), %0\n\t" + "addl (%%edx), %0" + : "=a" (a), "=&b" (b)); + printf (" = %d\n", a); + result |= a != 1; +#endif + + fputs ("get sum of foo and bar (GD)", stdout); + asm ("call 1f\n\t" + ".subsection 1\n" + "1:\tmovl (%%esp), %%ebx\n\t" + "ret\n\t" + ".previous\n\t" + "addl $_GLOBAL_OFFSET_TABLE_, %%ebx\n\t" + "leal foo@tlsgd(%%ebx),%%eax\n\t" + "call ___tls_get_addr@plt\n\t" + "nop\n\t" + "movl (%%eax), %%edx\n\t" + "leal bar@tlsgd(%%ebx),%%eax\n\t" + "call ___tls_get_addr@plt\n\t" + "nop\n\t" + "addl (%%eax), %%edx\n\t" + : "=&a" (a), "=d" (b)); + printf (" = %d\n", b); + result |= b != 1; + +# else +# error "No support for this architecture so far." +# endif + + return result; +#else + return 0; +#endif +} diff --git a/sysdeps/generic/dl-tls.c b/sysdeps/generic/dl-tls.c index 5c05baee0c..2c5fa75b62 100644 --- a/sysdeps/generic/dl-tls.c +++ b/sysdeps/generic/dl-tls.c @@ -112,21 +112,17 @@ _dl_determine_tlsoffset (struct link_map *firstp) } while ((runp = runp->l_tls_nextimage) != firstp); +#if 0 /* The thread descriptor (pointed to by the thread pointer) has its own alignment requirement. Adjust the static TLS size and TLS offsets appropriately. */ + // XXX How to deal with this. We cannot simply add zero bytes + // XXX after the first (closest to the TCB) TLS block since this + // XXX would invalidate the offsets the linker creates for the LE + // XXX model. if (offset % TLS_TCB_ALIGN != 0) - { - size_t add = TLS_TCB_ALIGN - offset % TLS_TCB_ALIGN; - - /* XXX If the offset stored is negative we must subtract here. */ - offset += add; - - runp = firstp; - do - runp->l_tls_offset += add; - while ((runp = runp->l_tls_nextimage) != firstp); - } + abort (); +#endif GL(dl_tls_static_size) = offset + TLS_TCB_SIZE; # elif TLS_DTV_AT_TP |