This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


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] Make any ld.so able to load NPTL+sysenter libc/libpthread


Hi!

ATM say --with-tls --without-__thread --enable-add-ons=linuxthreads
ld.so cannot load NPTL libc.so+libpthread.so (programs crash on first
ENTER_KERNEL) while this worked before the sysenter changes and should
continue to work IMHO.
The ld.so GL(dl_sysinfo) initialization needs to be done when there is
a chance this ld.so will load libraries using call ENTER_KERNEL instead
of int $0x80. The following patch (on top of earlier
http://sources.redhat.com/ml/libc-hacker/2002-12/msg00047.html
patch) fixes this by separating NEED_DL_SYSINFO and USE_DL_SYSINFO.
It also syncs tcbhead_t layouts on other arches between NPTL and
linuxthreads.

2002-12-27  Jakub Jelinek  <jakub@redhat.com>

linuxthreads/
	* sysdeps/i386/tls.h: Include dl-sysdep.h and stdint.h.
	(tcbhead_t): Add dummy1, dummy2 and sysinfo fields.
	(SYSINFO_OFFSET, INIT_SYSINFO): Define.
	(TLS_INIT_TP): Use INIT_SYSINFO.
	* sysdeps/ia64/tls.h (tcbhead_t): Add dummy1 and dummy2 fields.
	* sysdeps/sparc/sparc32/tls.h (tcbhead_t): Likewise.
	* sysdeps/sparc/sparc64/tls.h (tcbhead_t): Likewise.
	* sysdeps/unix/sysv/linux/i386/dl-sysdep.h: New file.
	* sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
	(MULTIPLE_THREADS_OFFSET): Adjust.
	* sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h
	(MULTIPLE_THREADS_OFFSET): Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h
	(MULTIPLE_THREADS_OFFSET): Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h
	(MULTIPLE_THREADS_OFFSET): Likewise.
	* descr.h: Include stdint.h.
	(struct _pthread_descr_struct): Add p_header.data.dummy[12]
	and p_header.data.sysinfo fields.
libc/
	* sysdeps/unix/sysv/linux/i386/sysdep.h (I386_USE_SYSENTER):
	Only define if USE_DL_SYSINFO is defined.
nptl/
	* sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h (USE_DL_SYSINFO):
	Define.
	(DL_SYSINFO_DEFAULT): Cast to uintptr_t to avoid warnings.
	* sysdeps/unix/sysv/linux/i386/dl-sysdep.h (NEED_DL_SYSINFO,
	DL_SYSINFO_DEFAULT, DL_SYSINFO_IMPLEMENTATION): Define.
	(USE_DL_SYSINFO): Undef.

--- libc/linuxthreads/sysdeps/i386/tls.h.jj	2002-12-27 13:57:59.000000000 +0100
+++ libc/linuxthreads/sysdeps/i386/tls.h	2002-12-27 21:32:36.000000000 +0100
@@ -20,10 +20,12 @@
 #ifndef _TLS_H
 #define _TLS_H
 
+# include <dl-sysdep.h>
 # include <pt-machine.h>
 
 #ifndef __ASSEMBLER__
 # include <stddef.h>
+# include <stdint.h>
 
 /* Type for the dtv.  */
 typedef union dtv
@@ -39,10 +41,18 @@ typedef struct
 			   thread descriptor used by libpthread.  */
   dtv_t *dtv;
   void *self;		/* Pointer to the thread descriptor.  */
+  void *dummy1, *dummy2; /* list_t in NPTL.  */
   int multiple_threads;
+#ifdef NEED_DL_SYSINFO
+  uintptr_t sysinfo;
+#endif
 } tcbhead_t;
 #endif
 
+#ifdef NEED_DL_SYSINFO
+/* Offset of the SYSINFO element in tcbhead_t.  */
+# define SYSINFO_OFFSET 24
+#endif
 
 /* We can support TLS only if the floating-stack support is available.
    However, we want to compile in the support and test at runtime whether
@@ -175,6 +185,12 @@ TLS_DO_MODIFY_LDT_KERNEL_CHECK(						   
   TLS_DO_MODIFY_LDT ((descr), 0)
 #  endif
 
+#if defined NEED_DL_SYSINFO && defined SHARED
+# define INIT_SYSINFO \
+  head->sysinfo = GL(dl_sysinfo)
+#else
+# define INIT_SYSINFO
+#endif
 
 /* Code to initially initialize the thread pointer.  This might need
    special attention since 'errno' is not yet available and if the
@@ -190,6 +206,7 @@ TLS_DO_MODIFY_LDT_KERNEL_CHECK(						   
     /* For now the thread descriptor is at the same address.  */	      \
     head->self = _descr;						      \
 									      \
+    INIT_SYSINFO;							      \
     TLS_SETUP_GS_SEGMENT (_descr, secondcall);				      \
   })
 
--- libc/linuxthreads/sysdeps/ia64/tls.h.jj	2002-12-27 13:57:59.000000000 +0100
+++ libc/linuxthreads/sysdeps/ia64/tls.h	2002-12-27 14:09:56.000000000 +0100
@@ -42,6 +42,7 @@ typedef struct
 			   thread descriptor used by libpthread.  */
   dtv_t *dtv;
   void *self;		/* Pointer to the thread descriptor.  */
+  void *dummy1, *dummy2;
   int multiple_threads;
 } tcbhead_t;
 #endif /* __ASSEMBLER__ */
--- libc/linuxthreads/sysdeps/sparc/sparc32/tls.h.jj	2002-12-27 13:57:59.000000000 +0100
+++ libc/linuxthreads/sysdeps/sparc/sparc32/tls.h	2002-12-27 14:07:34.000000000 +0100
@@ -38,6 +38,7 @@ typedef struct
 			   thread descriptor used by libpthread.  */
   dtv_t *dtv;
   void *self;		/* Pointer to the thread descriptor.  */
+  void *dummy1, *dummy2;
   int multiple_threads;
 } tcbhead_t;
 
--- libc/linuxthreads/sysdeps/sparc/sparc64/tls.h.jj	2002-12-27 13:57:59.000000000 +0100
+++ libc/linuxthreads/sysdeps/sparc/sparc64/tls.h	2002-12-27 14:07:48.000000000 +0100
@@ -38,6 +38,7 @@ typedef struct
 			   thread descriptor used by libpthread.  */
   dtv_t *dtv;
   void *self;		/* Pointer to the thread descriptor.  */
+  void *dummy1, *dummy2;
   int multiple_threads;
 } tcbhead_t;
 
--- libc/linuxthreads/sysdeps/unix/sysv/linux/i386/dl-sysdep.h.jj	2002-12-27 13:49:19.000000000 +0100
+++ libc/linuxthreads/sysdeps/unix/sysv/linux/i386/dl-sysdep.h	2002-12-27 22:10:54.000000000 +0100
@@ -0,0 +1,60 @@
+/* System-specific settings for dynamic linker code.  IA-32 version.
+   Copyright (C) 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _DL_SYSDEP_H
+#define _DL_SYSDEP_H	1
+
+/* This macro must be defined to either 0 or 1.
+
+   If 1, then an errno global variable hidden in ld.so will work right with
+   all the errno-using libc code compiled for ld.so, and there is never a
+   need to share the errno location with libc.  This is appropriate only if
+   all the libc functions that ld.so uses are called without PLT and always
+   get the versions linked into ld.so rather than the libc ones.  */
+
+#ifdef IS_IN_rtld
+# define RTLD_PRIVATE_ERRNO 1
+#else
+# define RTLD_PRIVATE_ERRNO 0
+#endif
+
+/* Traditionally system calls have been made using int $0x80.  A
+   second method was introduced which, if possible, will use the
+   sysenter/syscall instructions.  To signal the presence and where to
+   find the code the kernel passes an AT_SYSINFO value in the
+   auxiliary vector to the application.
+   sysenter/syscall is not useful on i386 through i586, but the dynamic
+   linker and dl code in libc.a has to be able to load i686 compiled
+   libraries.  */
+#define NEED_DL_SYSINFO	1
+#undef USE_DL_SYSINFO
+
+#if defined NEED_DL_SYSINFO && !defined __ASSEMBLER__
+extern void _dl_sysinfo_int80 (void) attribute_hidden;
+# define DL_SYSINFO_DEFAULT (uintptr_t) _dl_sysinfo_int80
+# define DL_SYSINFO_IMPLEMENTATION \
+  asm (".type _dl_sysinfo_int80,@function\n\t"				      \
+       ".hidden _dl_sysinfo_int80\n"					      \
+       "_dl_sysinfo_int80:\n\t"						      \
+       "int $0x80;\n\t"							      \
+       "ret;\n\t"							      \
+       ".size _dl_sysinfo_int80,.-_dl_sysinfo_int80");
+#endif
+
+#endif	/* dl-sysdep.h */
--- libc/linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h.jj	2002-12-18 02:26:07.000000000 +0100
+++ libc/linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h	2002-12-27 14:11:58.000000000 +0100
@@ -25,7 +25,7 @@
 #endif
 
 #if defined FLOATING_STACKS && USE___THREAD
-# define MULTIPLE_THREADS_OFFSET	12
+# define MULTIPLE_THREADS_OFFSET	20
 #endif
 
 #if !defined NOT_IN_libc || defined IS_IN_libpthread
--- libc/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h.jj	2002-12-27 13:57:59.000000000 +0100
+++ libc/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h	2002-12-27 14:12:55.000000000 +0100
@@ -23,7 +23,7 @@
 # include <linuxthreads/internals.h>
 #endif
 
-#define MULTIPLE_THREADS_OFFSET	24
+#define MULTIPLE_THREADS_OFFSET	40
 
 #if !defined NOT_IN_libc || defined IS_IN_libpthread
 
--- libc/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h.jj	2002-12-27 13:57:59.000000000 +0100
+++ libc/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h	2002-12-27 14:12:13.000000000 +0100
@@ -23,7 +23,7 @@
 # include <linuxthreads/internals.h>
 #endif
 
-#define MULTIPLE_THREADS_OFFSET	12
+#define MULTIPLE_THREADS_OFFSET	20
 
 #if !defined NOT_IN_libc || defined IS_IN_libpthread
 
--- libc/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h.jj	2002-12-27 13:57:59.000000000 +0100
+++ libc/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h	2002-12-27 14:12:41.000000000 +0100
@@ -23,7 +23,7 @@
 # include <linuxthreads/internals.h>
 #endif
 
-#define MULTIPLE_THREADS_OFFSET	24
+#define MULTIPLE_THREADS_OFFSET	40
 
 #if !defined NOT_IN_libc || defined IS_IN_libpthread
 
--- libc/linuxthreads/descr.h.jj	2002-12-18 02:12:21.000000000 +0100
+++ libc/linuxthreads/descr.h	2002-12-27 21:47:14.000000000 +0100
@@ -20,6 +20,7 @@
 #include <sched.h>
 #include <setjmp.h>
 #include <signal.h>
+#include <stdint.h>
 #include <sys/types.h>
 #include <hp-timing.h>
 #include <bits/libc-tsd.h> /* for _LIBC_TSD_KEY_N */
@@ -106,7 +115,11 @@ struct _pthread_descr_struct {
 				   the address of this thread descriptor.  */
       union dtv *dtvp;
       pthread_descr self;	/* Pointer to this structure */
+      void *dummy1, *dummy2;	/* This is list_t in nptl */
       int multiple_threads;
+#ifdef NEED_DL_SYSINFO
+      uintptr_t sysinfo;
+#endif
     } data;
     void *__padding[16];
   } p_header;
--- libc/sysdeps/unix/sysv/linux/i386/sysdep.h.jj	2002-12-20 00:04:27.000000000 +0100
+++ libc/sysdeps/unix/sysv/linux/i386/sysdep.h	2002-12-27 13:47:48.000000000 +0100
@@ -24,7 +24,7 @@
 #include <sysdeps/unix/i386/sysdep.h>
 #include <bp-sym.h>
 #include <bp-asm.h>
-/* Defines RTLD_PRIVATE_ERRNO and NEED_DL_SYSINFO.  */
+/* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO.  */
 #include <dl-sysdep.h>
 #include <tls.h>
 
@@ -36,7 +36,8 @@
 #undef SYS_ify
 #define SYS_ify(syscall_name)	__NR_##syscall_name
 
-#if defined NEED_DL_SYSINFO && !defined IS_IN_rtld
+#if defined USE_DL_SYSINFO \
+    && (!defined NOT_IN_libc || defined IS_IN_libpthread)
 # define I386_USE_SYSENTER	1
 #else
 # undef I386_USE_SYSENTER
--- libc/nptl/sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h.jj	2002-12-27 13:33:24.000000000 +0100
+++ libc/nptl/sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h	2002-12-27 22:14:21.000000000 +0100
@@ -1,4 +1,4 @@
-/* System-specific settings for dynamic linker code.  Generic version.
+/* System-specific settings for dynamic linker code.  IA-32 version.
    Copyright (C) 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -49,10 +49,11 @@
    find the code the kernel passes an AT_SYSINFO value in the
    auxiliary vector to the application.  */
 #define NEED_DL_SYSINFO	1
+#define USE_DL_SYSINFO	1
 
 #if defined NEED_DL_SYSINFO && !defined __ASSEMBLER__
 extern void _dl_sysinfo_int80 (void) attribute_hidden;
-# define DL_SYSINFO_DEFAULT _dl_sysinfo_int80
+# define DL_SYSINFO_DEFAULT (uintptr_t) _dl_sysinfo_int80
 # define DL_SYSINFO_IMPLEMENTATION \
   asm (".type _dl_sysinfo_int80,@function\n\t"				      \
        ".hidden _dl_sysinfo_int80\n"					      \
--- libc/nptl/sysdeps/unix/sysv/linux/i386/dl-sysdep.h.jj	2002-12-25 00:20:54.000000000 +0100
+++ libc/nptl/sysdeps/unix/sysv/linux/i386/dl-sysdep.h	2002-12-27 22:14:09.000000000 +0100
@@ -1,4 +1,4 @@
-/* System-specific settings for dynamic linker code.  Generic version.
+/* System-specific settings for dynamic linker code.  IA-32 version.
    Copyright (C) 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -42,4 +42,28 @@
 
 #define RTLD_CORRECT_DYNAMIC_WEAK	1
 
+
+/* Traditionally system calls have been made using int $0x80.  A
+   second method was introduced which, if possible, will use the
+   sysenter/syscall instructions.  To signal the presence and where to
+   find the code the kernel passes an AT_SYSINFO value in the
+   auxiliary vector to the application.
+   sysenter/syscall is not useful on i386 through i586, but the dynamic
+   linker and dl code in libc.a has to be able to load i686 compiled
+   libraries.  */
+#define NEED_DL_SYSINFO	1
+#undef USE_DL_SYSINFO
+
+#if defined NEED_DL_SYSINFO && !defined __ASSEMBLER__
+extern void _dl_sysinfo_int80 (void) attribute_hidden;
+# define DL_SYSINFO_DEFAULT (uintptr_t) _dl_sysinfo_int80
+# define DL_SYSINFO_IMPLEMENTATION \
+  asm (".type _dl_sysinfo_int80,@function\n\t"				      \
+       ".hidden _dl_sysinfo_int80\n"					      \
+       "_dl_sysinfo_int80:\n\t"						      \
+       "int $0x80;\n\t"							      \
+       "ret;\n\t"							      \
+       ".size _dl_sysinfo_int80,.-_dl_sysinfo_int80");
+#endif
+
 #endif	/* dl-sysdep.h */

	Jakub


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