This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: PR libc/12113: Segmentation fault in dynamic loader on AVXenabled OS and CPU with AVX


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;
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]