269 lines
8.9 KiB
Diff
269 lines
8.9 KiB
Diff
|
Gentoo bug #52374.
|
||
|
==================
|
||
|
|
||
|
Note, this patch includes both:
|
||
|
|
||
|
-----
|
||
|
2005-01-10 Ulrich Drepper <drepper@redhat.com>
|
||
|
|
||
|
* sysdeps/generic/dl-tls.c (_dl_next_tls_modid): Fix assertion and
|
||
|
recognition of last entry.
|
||
|
-----
|
||
|
|
||
|
and:
|
||
|
|
||
|
-----
|
||
|
2005-03-15 Jakub Jelinek <jakub@redhat.com>
|
||
|
|
||
|
[BZ#786]
|
||
|
* sysdeps/generic/dl-tls.c (_dl_next_tls_modid): Handle
|
||
|
GL(dl_tls_static_nelem) == GL(dl_tls_max_dtv_idx).
|
||
|
* elf/Makefile: Add rules to build and run tst-tls15.
|
||
|
* elf/tst-tls15.c: New test.
|
||
|
* elf/tst-tlsmod15a.c: New file.
|
||
|
* elf/tst-tlsmod15b.c: New file.
|
||
|
-----
|
||
|
|
||
|
================================================================================
|
||
|
On Sun, Mar 13, 2005 at 09:39:04PM +0200, Martin Schlemmer wrote:
|
||
|
> Basically the issue above. This is valid for glibc 2.3.[234] if I did
|
||
|
> not miss anything. Here is a good test case:
|
||
|
>
|
||
|
> http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=219352#msg122
|
||
|
>
|
||
|
> I came up with attached patch that seems to work and passes all the
|
||
|
> tests (except for the one or two usual ones). Is this the correct fix,
|
||
|
> or are the problem deeper?
|
||
|
>
|
||
|
>--- glibc-2.3.4/sysdeps/generic/dl-tls.c.az 2005-03-13 19:26:55.000000000 +0200
|
||
|
>+++ glibc-2.3.4/sysdeps/generic/dl-tls.c 2005-03-13 19:29:14.000000000 +0200
|
||
|
>@@ -69,7 +69,10 @@
|
||
|
> 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));
|
||
|
>+ /* The +1 is needed, as we add +1 above, but dl_tls_static_nelem
|
||
|
>+ is only once set as far as I can see in dl_main (elf/rtld.c),
|
||
|
>+ and that is equal to dl_tls_max_dtv_idx ... */
|
||
|
>+ assert (result <= (GL(dl_tls_max_dtv_idx) + 1));
|
||
|
> do
|
||
|
> {
|
||
|
> while (result - disp < runp->len)
|
||
|
>@@ -92,7 +95,8 @@
|
||
|
> {
|
||
|
> /* The new index must indeed be exactly one higher than the
|
||
|
> previous high. */
|
||
|
>- assert (result == GL(dl_tls_max_dtv_idx));
|
||
|
>+ /* Once again +1 for the same reasons as above ... */
|
||
|
>+ assert (result == (GL(dl_tls_max_dtv_idx) + 1));
|
||
|
>
|
||
|
> /* There is no gap anymore. */
|
||
|
> GL(dl_tls_dtv_gaps) = false;
|
||
|
>
|
||
|
|
||
|
That patch certainly doesn't apply to neither HEAD nor glibc-2_3-branch,
|
||
|
see especially:
|
||
|
2005-01-10 Ulrich Drepper <drepper@redhat.com>
|
||
|
|
||
|
* sysdeps/generic/dl-tls.c (_dl_next_tls_modid): Fix assertion and
|
||
|
recognition of last entry.
|
||
|
|
||
|
The fix can either be that dl-open.c only sets GL(dl_tls_dtv_gaps)
|
||
|
to true if GL(dl_tls_static_nelem) < GL(dl_tls_max_dtv_idx)
|
||
|
(if it is equal, there are certainly no gaps), or handling that case
|
||
|
in _dl_next_tls_modid. In _dl_next_tls_modid, the choices are either
|
||
|
to do what the patch below does, i.e. just clear GL(dl_tls_dtv_gaps)
|
||
|
if that happens, or just change the assert and let the do ... while
|
||
|
loop run, it shouldn't increment result anyway.
|
||
|
|
||
|
2005-03-15 Jakub Jelinek <jakub@redhat.com>
|
||
|
|
||
|
[BZ#786]
|
||
|
* sysdeps/generic/dl-tls.c (_dl_next_tls_modid): Handle
|
||
|
GL(dl_tls_static_nelem) == GL(dl_tls_max_dtv_idx).
|
||
|
* elf/Makefile: Add rules to build and run tst-tls15.
|
||
|
* elf/tst-tls15.c: New test.
|
||
|
* elf/tst-tlsmod15a.c: New file.
|
||
|
* elf/tst-tlsmod15b.c: New file.
|
||
|
|
||
|
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 <dlfcn.h>
|
||
|
+#include <stdio.h>
|
||
|
+
|
||
|
+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;
|