diff options
author | Ulrich Drepper <drepper@redhat.com> | 2003-07-24 20:07:00 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2003-07-24 20:07:00 +0000 |
commit | 99fe3b0e7a0a9d72152cc86df0571c231c83cae4 (patch) | |
tree | cea072329bb202a3a432a17d1fd3d7d77d8cea10 /elf/dl-reloc.c | |
parent | 6bc0b95489067acc56efb0d8e1d88fe18644389f (diff) | |
download | glibc-99fe3b0e7a0a9d72152cc86df0571c231c83cae4.tar.gz glibc-99fe3b0e7a0a9d72152cc86df0571c231c83cae4.tar.xz glibc-99fe3b0e7a0a9d72152cc86df0571c231c83cae4.zip |
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.
Diffstat (limited to 'elf/dl-reloc.c')
-rw-r--r-- | elf/dl-reloc.c | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index 6165fe4aca..d82ea108d0 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -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)) { @@ -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 @@ -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" |