Submitted By: DJ Lucas Date: 2005-11-20 Initial Package Version: 2.3.4 Upstream Status: Comitted Origin: http://bugs.gentoo.org/show_bug.cgi?id=52374#c23 Description: Fixes the follwoing error: Inconsistency detected by ld.so: ../sysdeps/generic/dl-tls.c: 72: _dl_next_tls_modid: Assertion `result <= _rtld_local._dl_tls_max_dtv_idx' failed! diff -urpN glibc-2.3.4.az/elf/Makefile glibc-2.3.4/elf/Makefile --- glibc-2.3.4.az/elf/Makefile 2005-03-15 17:38:36.000000000 +0200 +++ glibc-2.3.4/elf/Makefile 2005-03-15 17:39:07.000000000 +0200 @@ -152,7 +152,7 @@ tests += loadtest restest1 preloadtest l 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-tls14 tst-align \ + tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-tls15 tst-align \ $(tests-execstack-$(have-z-execstack)) tst-dlmodcount \ tst-dlopenrpath tst-deep1 tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 # reldep9 @@ -182,6 +182,7 @@ modules-names = testobj1 testobj2 testob tst-tlsmod5 tst-tlsmod6 tst-tlsmod7 tst-tlsmod8 \ tst-tlsmod9 tst-tlsmod10 tst-tlsmod11 tst-tlsmod12 \ tst-tlsmod13 tst-tlsmod13a tst-tlsmod14a tst-tlsmod14b \ + tst-tlsmod15a tst-tlsmod15b \ circlemod1 circlemod1a circlemod2 circlemod2a \ circlemod3 circlemod3a \ reldep8mod1 reldep8mod2 reldep8mod3 \ @@ -454,6 +455,7 @@ 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 +tst-tlsmod15a.so-no-z-defs = yes circlemod2.so-no-z-defs = yes circlemod3.so-no-z-defs = yes circlemod3a.so-no-z-defs = yes @@ -664,8 +666,11 @@ $(objpfx)tst-tls12: $(objpfx)tst-tlsmod1 $(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 +$(objpfx)tst-tls14: $(objpfx)tst-tlsmod14a.so $(libdl) +$(objpfx)tst-tls14.out: $(objpfx)tst-tlsmod14b.so + +$(objpfx)tst-tls15: $(libdl) +$(objpfx)tst-tls15.out: $(objpfx)tst-tlsmod15a.so $(objpfx)tst-tlsmod15b.so CFLAGS-tst-align.c = $(stack-align-test-flags) CFLAGS-tst-alignmod.c = $(stack-align-test-flags) diff -urpN glibc-2.3.4.az/elf/tst-tls15.c glibc-2.3.4/elf/tst-tls15.c --- glibc-2.3.4.az/elf/tst-tls15.c 1970-01-01 02:00:00.000000000 +0200 +++ glibc-2.3.4/elf/tst-tls15.c 2005-03-15 17:39:07.000000000 +0200 @@ -0,0 +1,32 @@ +#include +#include + +static int +do_test (void) +{ + void *h = dlopen ("tst-tlsmod15a.so", RTLD_NOW); + if (h != NULL) + { + puts ("unexpectedly succeeded to open tst-tlsmod15a.so"); + exit (1); + } + + h = dlopen ("tst-tlsmod15b.so", RTLD_NOW); + if (h == NULL) + { + puts ("failed to open tst-tlsmod15b.so"); + exit (1); + } + + int (*fp) (void) = (int (*) (void)) dlsym (h, "in_dso"); + if (fp == NULL) + { + puts ("cannot find in_dso"); + exit (1); + } + + return fp (); +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff -urpN glibc-2.3.4.az/elf/tst-tlsmod15a.c glibc-2.3.4/elf/tst-tlsmod15a.c --- glibc-2.3.4.az/elf/tst-tlsmod15a.c 1970-01-01 02:00:00.000000000 +0200 +++ glibc-2.3.4/elf/tst-tlsmod15a.c 2005-03-15 17:39:07.000000000 +0200 @@ -0,0 +1,6 @@ +extern int nonexistent_dummy_var; +int * +foo (void) +{ + return &nonexistent_dummy_var; +} diff -urpN glibc-2.3.4.az/elf/tst-tlsmod15b.c glibc-2.3.4/elf/tst-tlsmod15b.c --- glibc-2.3.4.az/elf/tst-tlsmod15b.c 1970-01-01 02:00:00.000000000 +0200 +++ glibc-2.3.4/elf/tst-tlsmod15b.c 2005-03-15 17:39:07.000000000 +0200 @@ -0,0 +1,17 @@ +#include "tst-tls10.h" + +#ifdef USE_TLS__THREAD +__thread int mod15b_var __attribute__((tls_model("initial-exec"))); + +int +in_dso (void) +{ + return mod15b_var; +} +#else +int +in_dso (void) +{ + return 0; +} +#endif diff -urpN glibc-2.3.4.az/sysdeps/generic/dl-tls.c glibc-2.3.4/sysdeps/generic/dl-tls.c --- glibc-2.3.4.az/sysdeps/generic/dl-tls.c 2005-03-15 17:40:56.000000000 +0200 +++ glibc-2.3.4/sysdeps/generic/dl-tls.c 2005-03-15 17:39:07.000000000 +0200 @@ -65,34 +65,35 @@ _dl_next_tls_modid (void) /* Note that this branch will never be executed during program start since there are no gaps at that time. Therefore it does not matter that the dl_tls_dtv_slotinfo is not allocated - yet when the function is called for the first times. */ - result = GL(dl_tls_static_nelem) + 1; - /* If the following would not be true we mustn't have assumed - there is a gap. */ - assert (result <= GL(dl_tls_max_dtv_idx)); - do - { - while (result - disp < runp->len) - { - if (runp->slotinfo[result - disp].map == NULL) - break; - - ++result; - assert (result <= GL(dl_tls_max_dtv_idx) + 1); - } + yet when the function is called for the first times. - if (result - disp < runp->len) - break; - - disp += runp->len; - } - while ((runp = runp->next) != NULL); + NB: the offset +1 is due to the fact that DTV[0] is used + for something else. */ + result = GL(dl_tls_static_nelem) + 1; + if (result <= GL(dl_tls_max_dtv_idx)) + do + { + while (result - disp < runp->len) + { + if (runp->slotinfo[result - disp].map == NULL) + break; + + ++result; + assert (result <= GL(dl_tls_max_dtv_idx) + 1); + } + + if (result - disp < runp->len) + break; + + disp += runp->len; + } + while ((runp = runp->next) != NULL); - if (result >= GL(dl_tls_max_dtv_idx)) + if (result > GL(dl_tls_max_dtv_idx)) { /* The new index must indeed be exactly one higher than the previous high. */ - assert (result == GL(dl_tls_max_dtv_idx)); + assert (result == GL(dl_tls_max_dtv_idx) + 1); /* There is no gap anymore. */ GL(dl_tls_dtv_gaps) = false; @@ -577,7 +578,7 @@ __tls_get_addr (GET_ADDR_ARGS) { size_t cnt; - for (cnt = total = 0 ? 1 : 0; cnt < listp->len; ++cnt) + for (cnt = total == 0 ? 1 : 0; cnt < listp->len; ++cnt) { size_t gen = listp->slotinfo[cnt].gen; struct link_map *map;