Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Update.
2003-07-24  Ulrich Drepper  <drepper@redhat.com>

	* include/link.h (struct link_map): Add l_tls_firstbyte_offset field.
	* sysdeps/generic/dl-tls.c [TLS_TCB_AT_TP] (_dl_determine_tlsoffset):
	Fix calculation of offsets to take misalignment of first byte in
	file into account.
	* elf/dl-load.c (_dl_map_object_from_fd): Initialize
	l_tls_firstbyte_offset field.
	* elf/rtld.c (_dl_start_final, _dl_start, dl_main): Likewise.
	* elf/dl-reloc.c (_dl_allocate_static_tls): Change return type to int.
	Take l_tls_firstbyte_offset information into account.
	(CHECK_STATIS_TLS): _dl_allocate_static_tls can fail now.
	* sysdeps/generic/ldsodefs.h: Adjust _dl_allocate_static_tls prototype.
	* elf/Makefile: Add rules to build and run tst-tls14.
	* elf/tst-tls14.c: New file.
	* elf/tst-tlsmod14a.c: New file.
	* elf/tst-tlsmod14b.c: New file.
  • Loading branch information
Ulrich Drepper committed Jul 24, 2003
1 parent 6bc0b95 commit 99fe3b0
Show file tree
Hide file tree
Showing 11 changed files with 231 additions and 22 deletions.
18 changes: 18 additions & 0 deletions ChangeLog
@@ -1,3 +1,21 @@
2003-07-24 Ulrich Drepper <drepper@redhat.com>

* include/link.h (struct link_map): Add l_tls_firstbyte_offset field.
* sysdeps/generic/dl-tls.c [TLS_TCB_AT_TP] (_dl_determine_tlsoffset):
Fix calculation of offsets to take misalignment of first byte in
file into account.
* elf/dl-load.c (_dl_map_object_from_fd): Initialize
l_tls_firstbyte_offset field.
* elf/rtld.c (_dl_start_final, _dl_start, dl_main): Likewise.
* elf/dl-reloc.c (_dl_allocate_static_tls): Change return type to int.
Take l_tls_firstbyte_offset information into account.
(CHECK_STATIS_TLS): _dl_allocate_static_tls can fail now.
* sysdeps/generic/ldsodefs.h: Adjust _dl_allocate_static_tls prototype.
* elf/Makefile: Add rules to build and run tst-tls14.
* elf/tst-tls14.c: New file.
* elf/tst-tlsmod14a.c: New file.
* elf/tst-tlsmod14b.c: New file.

2003-07-23 Jakub Jelinek <jakub@redhat.com>

* sysdeps/pthread/lio_listio.c (LIO_OPCODE_BASE): Define.
Expand Down
9 changes: 7 additions & 2 deletions elf/Makefile
Expand Up @@ -148,7 +148,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
neededtest3 neededtest4 unload2 lateglobal initfirst global \
restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \
circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \
tst-tls10 tst-tls11 tst-tls12 tst-tls13
tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14
# reldep9
test-srcs = tst-pathopt
tests-vis-yes = vismain
Expand All @@ -171,7 +171,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
tst-tlsmod1 tst-tlsmod2 tst-tlsmod3 tst-tlsmod4 \
tst-tlsmod5 tst-tlsmod6 tst-tlsmod7 tst-tlsmod8 \
tst-tlsmod9 tst-tlsmod10 tst-tlsmod11 tst-tlsmod12 \
tst-tlsmod13 tst-tlsmod13a \
tst-tlsmod13 tst-tlsmod13a tst-tlsmod14a tst-tlsmod14b \
circlemod1 circlemod1a circlemod2 circlemod2a \
circlemod3 circlemod3a \
reldep8mod1 reldep8mod2 reldep8mod3 \
Expand Down Expand Up @@ -428,6 +428,8 @@ tst-tlsmod8.so-no-z-defs = yes
tst-tlsmod9.so-no-z-defs = yes
tst-tlsmod10.so-no-z-defs = yes
tst-tlsmod12.so-no-z-defs = yes
tst-tlsmod14a.so-no-z-defs = yes
tst-tlsmod14b.so-no-z-defs = yes
circlemod2.so-no-z-defs = yes
circlemod3.so-no-z-defs = yes
circlemod3a.so-no-z-defs = yes
Expand Down Expand Up @@ -633,6 +635,9 @@ $(objpfx)tst-tls12: $(objpfx)tst-tlsmod12.so
$(objpfx)tst-tls13: $(libdl)
$(objpfx)tst-tls13.out: $(objpfx)tst-tlsmod13a.so

$(objpfx)tst-tls14: $(objpfx)tst-tlsmod14a.so $(libdl)
$(objpfx)tst-tls14.out:$(objpfx)tst-tlsmod14b.so

ifdef libdl
$(objpfx)tst-tls9-static: $(common-objpfx)dlfcn/libdl.a
$(objpfx)tst-tls9-static.out: $(objpfx)tst-tlsmod5.so $(objpfx)tst-tlsmod6.so
Expand Down
4 changes: 4 additions & 0 deletions elf/dl-load.c
Expand Up @@ -987,6 +987,10 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,

l->l_tls_blocksize = ph->p_memsz;
l->l_tls_align = ph->p_align;
if (ph->p_align == 0)
l->l_tls_firstbyte_offset = 0;
else
l->l_tls_firstbyte_offset = ph->p_vaddr & (ph->p_align - 1);
l->l_tls_initimage_size = ph->p_filesz;
/* Since we don't know the load address yet only store the
offset. We will adjust it later. */
Expand Down
37 changes: 28 additions & 9 deletions elf/dl-reloc.c
Expand Up @@ -41,27 +41,39 @@
the static TLS area already allocated for each running thread. If this
object's TLS segment is too big to fit, we fail. If it fits,
we set MAP->l_tls_offset and return. */
void
int
internal_function __attribute_noinline__
_dl_allocate_static_tls (struct link_map *map)
{
size_t offset;
size_t used;
size_t check;
size_t freebytes;
size_t n;
size_t blsize;

/* If the alignment requirements are too high fail. */
if (map->l_tls_align > GL(dl_tls_static_align))
return 1;

# if TLS_TCB_AT_TP
offset = roundup (GL(dl_tls_static_used) + map->l_tls_blocksize,
map->l_tls_align);
used = offset;
check = offset + TLS_TCB_SIZE;
freebytes = GL(dl_tls_static_size) - GL(dl_tls_static_used) - TLS_TCB_SIZE;

blsize = map->l_tls_blocksize + map->l_tls_firstbyte_offset;
if (freebytes < blsize)
return 1;

n = (freebytes - blsize) / map->l_tls_align;

offset = GL(dl_tls_static_used) + (freebytes - n * map->l_tls_align
- map->l_tls_firstbyte_offset);

map->l_tls_offset = GL(dl_tls_static_used) = offset;
# elif TLS_DTV_AT_TP
offset = roundup (GL(dl_tls_static_used), map->l_tls_align);
used = offset + map->l_tls_blocksize;
check = used;
/* dl_tls_static_used includes the TCB at the beginning. */
# else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
# endif

if (check > GL(dl_tls_static_size))
{
Expand All @@ -72,6 +84,11 @@ shared object cannot be dlopen()ed: static TLS memory too small");

map->l_tls_offset = offset;
GL(dl_tls_static_used) = used;
# else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
# endif

return 0;
}
#endif

Expand Down Expand Up @@ -212,7 +229,9 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
#define CHECK_STATIC_TLS(map, sym_map) \
do { \
if (__builtin_expect ((sym_map)->l_tls_offset == NO_TLS_OFFSET, 0)) \
_dl_allocate_static_tls (sym_map); \
if (_dl_allocate_static_tls (sym_map) != 0) \
INTUSE(_dl_signal_error) (0, sym_map->l_name, NULL, N_("\
cannot allocate memory in static TLS block")); \
} while (0)

#include "dynamic-link.h"
Expand Down
11 changes: 11 additions & 0 deletions elf/rtld.c
Expand Up @@ -227,6 +227,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
assert (info->l.l_tls_modid != 0);
GL(dl_rtld_map).l_tls_blocksize = info->l.l_tls_blocksize;
GL(dl_rtld_map).l_tls_align = info->l.l_tls_align;
GL(dl_rtld_map).l_tls_firstbyte_offset = info->l.l_tls_firstbyte_offset;
GL(dl_rtld_map).l_tls_initimage_size = info->l.l_tls_initimage_size;
GL(dl_rtld_map).l_tls_initimage = info->l.l_tls_initimage;
GL(dl_rtld_map).l_tls_offset = info->l.l_tls_offset;
Expand Down Expand Up @@ -347,6 +348,11 @@ _dl_start (void *arg)

bootstrap_map.l_tls_blocksize = phdr[cnt].p_memsz;
bootstrap_map.l_tls_align = phdr[cnt].p_align;
if (phdr[cnt].p_align == 0)
bootstrap_map.l_tls_firstbyte_offset = 0;
else
bootstrap_map.l_tls_firstbyte_offset = (phdr[cnt].p_vaddr
& (phdr[cnt].p_align - 1));
assert (bootstrap_map.l_tls_blocksize != 0);
bootstrap_map.l_tls_initimage_size = phdr[cnt].p_filesz;
bootstrap_map.l_tls_initimage = (void *) (bootstrap_map.l_addr
Expand Down Expand Up @@ -860,6 +866,11 @@ of this helper program; chances are you did not intend to run this program.\n\
check for this special but unimportant case. */
GL(dl_loaded)->l_tls_blocksize = ph->p_memsz;
GL(dl_loaded)->l_tls_align = ph->p_align;
if (ph->p_align == 0)
GL(dl_loaded)->l_tls_firstbyte_offset = 0;
else
GL(dl_loaded)->l_tls_firstbyte_offset = (ph->p_vaddr
& (ph->p_align - 1));
GL(dl_loaded)->l_tls_initimage_size = ph->p_filesz;
GL(dl_loaded)->l_tls_initimage = (void *) ph->p_vaddr;

Expand Down
56 changes: 56 additions & 0 deletions elf/tst-tls14.c
@@ -0,0 +1,56 @@
/* Check alignment of TLS variable. */
#include <dlfcn.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>


#define AL 4096
struct foo
{
int i;
} __attribute ((aligned (AL)));

static __thread struct foo f;
static struct foo g;


extern int in_dso1 (void);


static int
do_test (void)
{
int result = 0;

int fail = (((uintptr_t) &f) & (AL - 1)) != 0;
printf ("&f = %p %s\n", &f, fail ? "FAIL" : "OK");
result |= fail;

fail = (((uintptr_t) &g) & (AL - 1)) != 0;
printf ("&g = %p %s\n", &g, fail ? "FAIL" : "OK");
result |= fail;

result |= in_dso1 ();

void *h = dlopen ("tst-tlsmod14b.so", RTLD_LAZY);
if (h == NULL)
{
printf ("cannot open tst-tlsmod14b.so: %m\n");
exit (1);
}

int (*fp) (void) = (int (*) (void)) dlsym (h, "in_dso2");
if (fp == NULL)
{
puts ("cannot find in_dso2");
exit (1);
}

result |= fp ();

return result;
}

#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
36 changes: 36 additions & 0 deletions elf/tst-tlsmod14a.c
@@ -0,0 +1,36 @@
#include <stdint.h>
#include <stdio.h>


#define AL 4096
struct foo
{
int i;
} __attribute ((aligned (AL)));

static __thread struct foo f;
static struct foo g;


#ifndef FCT
# define FCT in_dso1
#endif


int
FCT (void)
{
puts (__func__);

int result = 0;

int fail = (((uintptr_t) &f) & (AL - 1)) != 0;
printf ("&f = %p %s\n", &f, fail ? "FAIL" : "OK");
result |= fail;

fail = (((uintptr_t) &g) & (AL - 1)) != 0;
printf ("&g = %p %s\n", &g, fail ? "FAIL" : "OK");
result |= fail;

return result;
}
2 changes: 2 additions & 0 deletions elf/tst-tlsmod14b.c
@@ -0,0 +1,2 @@
#define FCT in_dso2
#include "tst-tlsmod14a.c"
4 changes: 3 additions & 1 deletion include/link.h
@@ -1,6 +1,6 @@
/* Data structure for communication from the run-time dynamic linker for
loaded ELF shared objects.
Copyright (C) 1995-1999,2000,01,02 Free Software Foundation, Inc.
Copyright (C) 1995-2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
Expand Down Expand Up @@ -268,6 +268,8 @@ struct link_map
size_t l_tls_blocksize;
/* Alignment requirement of the TLS block. */
size_t l_tls_align;
/* Offset of first byte module alignment. */
size_t l_tls_firstbyte_offset;
# ifndef NO_TLS_OFFSET
# define NO_TLS_OFFSET 0
# endif
Expand Down

0 comments on commit 99fe3b0

Please sign in to comment.