* 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.

	loop to initialize TLS block.
This commit is contained in:
Ulrich Drepper 2002-02-10 07:44:36 +00:00
parent 3065b0c799
commit b123d06e21
5 changed files with 100 additions and 15 deletions

View File

@ -1,7 +1,16 @@
2002-02-09 Ulrich Drepper <drepper@redhat.com> 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 * 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> 2002-02-08 Richard Henderson <rth@twiddle.net>

View File

@ -117,7 +117,7 @@ tests = loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
reldep reldep2 reldep3 reldep4 $(tests-nodelete-$(have-z-nodelete)) \ reldep reldep2 reldep3 reldep4 $(tests-nodelete-$(have-z-nodelete)) \
$(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \ $(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \
neededtest3 neededtest4 unload2 lateglobal initfirst global \ neededtest3 neededtest4 unload2 lateglobal initfirst global \
restest2 next dblload dblunload reldep5 reldep6 restest2 next dblload dblunload reldep5 reldep6 tst-tls1
test-srcs = tst-pathopt test-srcs = tst-pathopt
tests-vis-yes = vismain tests-vis-yes = vismain
tests-nodelete-yes = nodelete tests-nodelete-yes = nodelete

View File

@ -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_blocksize = ph->p_memsz;
GL(dl_loaded)->l_tls_align = ph->p_align; 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_size = ph->p_filesz;
GL(dl_loaded)->l_tls_initimage = (void *) (GL(dl_loaded)->l_addr GL(dl_loaded)->l_tls_initimage = (void *) ph->p_vaddr;
+ ph->p_offset);
/* This is the first element of the initialization image list. /* This is the first element of the initialization image list.
We create the list as circular since we have to append at We create the list as circular since we have to append at
the end. */ the end. */

81
elf/tst-tls1.c Normal file
View File

@ -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
}

View File

@ -112,21 +112,17 @@ _dl_determine_tlsoffset (struct link_map *firstp)
} }
while ((runp = runp->l_tls_nextimage) != firstp); while ((runp = runp->l_tls_nextimage) != firstp);
#if 0
/* The thread descriptor (pointed to by the thread pointer) has its /* The thread descriptor (pointed to by the thread pointer) has its
own alignment requirement. Adjust the static TLS size own alignment requirement. Adjust the static TLS size
and TLS offsets appropriately. */ 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) if (offset % TLS_TCB_ALIGN != 0)
{ abort ();
size_t add = TLS_TCB_ALIGN - offset % TLS_TCB_ALIGN; #endif
/* 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);
}
GL(dl_tls_static_size) = offset + TLS_TCB_SIZE; GL(dl_tls_static_size) = offset + TLS_TCB_SIZE;
# elif TLS_DTV_AT_TP # elif TLS_DTV_AT_TP