This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
PATCH: PR libc/12113: Segmentation fault in dynamic loader on AVXenabled OS and CPU with AVX
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: GNU C Library <libc-alpha at sourceware dot org>
- Date: Wed, 13 Oct 2010 05:06:09 -0700
- Subject: PATCH: PR libc/12113: Segmentation fault in dynamic loader on AVXenabled OS and CPU with AVX
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
Hi,
We need to align rtld_savespace_sse in tcbhead_t to maximum register
size. Otherwise, _dl_x86_64_save_sse may save/restore AVX registers
at unaligned address with aligned instructions.
Thanks.
H.J.
2010-10-13 H.J. Lu <hongjiu.lu@intel.com>
PR libc/12113
* dl1.h: New.
* dl1mod1.c: Likewise.
* dl1mod2.c: Likewise.
* tst-dl1.c: Likewise.
* Makefile (distribute): Add dl1.h.
(tests): Add tst-dl1.
(modules-names): Add dl1mod1 and dl1mod2.
(tst-dl1mod1.so-no-z-defs): New.
(tst-dl1mod2.so-no-z-defs): Likewise.
($(objpfx)tst-dl1): Likewise.
($(objpfx)tst-dl1.out): Likewise.
($(objpfx)dl1mod1.so): Likewise.
* sysdeps/x86_64/tls.h (tcbhead_t): Align rtld_savespace_sse
to "sizeof (__m128) * 4" bytes.
diff --git a/nptl/Makefile b/nptl/Makefile
index 51b6ae5..fc5fdc1 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -269,7 +269,7 @@ tests-nolibpthread = tst-unload
# of the page size since every architecture's page size is > 1k.
tst-oddstacklimit-ENV = ; ulimit -s 1023;
-distribute = eintr.c tst-cleanup4aux.c
+distribute = eintr.c tst-cleanup4aux.c dl1.h
gen-as-const-headers = pthread-errnos.sym
@@ -288,7 +288,7 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \
endif
ifeq ($(build-shared),yes)
tests += tst-atfork2 tst-tls3 tst-tls4 tst-tls5 tst-_res1 tst-fini1 \
- tst-stackguard1
+ tst-stackguard1 tst-dl1
tests-nolibpthread += tst-fini1
ifeq ($(have-z-execstack),yes)
tests += tst-execstack
@@ -298,7 +298,8 @@ endif
modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \
tst-tls5modd tst-tls5mode tst-tls5modf \
- tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod
+ tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod \
+ dl1mod1 dl1mod2
extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) tst-cleanup4aux.o
test-extras += $(modules-names)
test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names)))
@@ -312,6 +313,8 @@ tst-tls5modc.so-no-z-defs = yes
tst-tls5modd.so-no-z-defs = yes
tst-tls5mode.so-no-z-defs = yes
tst-tls5modf.so-no-z-defs = yes
+tst-dl1mod1.so-no-z-defs = yes
+tst-dl1mod2.so-no-z-defs = yes
ifeq ($(build-shared),yes)
# Build all the modules even when not actually running test programs.
@@ -508,6 +511,11 @@ endif
LDFLAGS-tst-cancel24 = -lstdc++
+$(objpfx)tst-dl1: $(libdl) $(shared-thread-library)
+$(objpfx)tst-dl1.out: $(objpfx)dl1mod1.so $(objpfx)dl1mod2.so
+
+$(objpfx)dl1mod1.so: $(objpfx)dl1mod2.so
+
extra-B-pthread.so = -B$(common-objpfx)nptl/
$(objpfx)libpthread.so: $(addprefix $(objpfx),$(crti-objs) $(crtn-objs))
$(objpfx)libpthread.so: +preinit += $(addprefix $(objpfx),$(crti-objs))
diff --git a/nptl/dl1.h b/nptl/dl1.h
new file mode 100644
index 0000000..04e88f4
--- /dev/null
+++ b/nptl/dl1.h
@@ -0,0 +1,10 @@
+#include <stdio.h>
+
+extern void hello1 (void);
+extern void hello2 (void);
+
+void
+hello (void)
+{
+ printf("Hello, World!\n");
+}
diff --git a/nptl/dl1mod1.c b/nptl/dl1mod1.c
new file mode 100644
index 0000000..b1c37ee
--- /dev/null
+++ b/nptl/dl1mod1.c
@@ -0,0 +1,8 @@
+#include "dl1.h"
+
+void
+hello1 (void)
+{
+ hello ();
+ hello2 ();
+}
diff --git a/nptl/dl1mod2.c b/nptl/dl1mod2.c
new file mode 100644
index 0000000..d93615a
--- /dev/null
+++ b/nptl/dl1mod2.c
@@ -0,0 +1,7 @@
+#include "dl1.h"
+
+void
+hello2(void)
+{
+ hello ();
+}
diff --git a/nptl/sysdeps/x86_64/tls.h b/nptl/sysdeps/x86_64/tls.h
index e39eb5f..817c9ae 100644
--- a/nptl/sysdeps/x86_64/tls.h
+++ b/nptl/sysdeps/x86_64/tls.h
@@ -68,8 +68,10 @@ typedef struct
void *__private_tm[5];
# if __WORDSIZE == 64
long int __unused2;
- /* Have space for the post-AVX register size. */
- __m128 rtld_savespace_sse[8][4];
+ /* Have space for the post-AVX register size. Must be aligned at
+ maximum register size. */
+ __m128 rtld_savespace_sse[8][4]
+ __attribute__ ((aligned (sizeof (__m128) * 4)));
void *__padding[8];
# endif
diff --git a/nptl/tst-dl1.c b/nptl/tst-dl1.c
new file mode 100644
index 0000000..eaaf7f1
--- /dev/null
+++ b/nptl/tst-dl1.c
@@ -0,0 +1,23 @@
+#include <dlfcn.h>
+#include <assert.h>
+#include <pthread.h>
+
+void* doTask(void* data)
+{
+ void* handle = dlopen("dl1mod1.so", RTLD_LAZY);
+ assert(handle);
+ typedef int (*hello_t)(void);
+ hello_t hello1 = (hello_t)dlsym(handle, "hello1");
+ assert(dlerror() == 0);
+ hello1();
+ return NULL;
+}
+
+int main()
+{
+ pthread_t tid;
+ pthread_create(&tid, NULL, &doTask, NULL);
+ pthread_join(tid, NULL);
+
+ return 0;
+}