* [Linux-ia64] glibc fsyscall patch
@ 2003-04-09 2:38 Ian Wienand
0 siblings, 0 replies; only message in thread
From: Ian Wienand @ 2003-04-09 2:38 UTC (permalink / raw)
To: linux-ia64
[-- Attachment #1: Type: text/plain, Size: 1045 bytes --]
Hello,
An updated version of David M's patch posted at
https://lists.linuxia64.org/archives//linux-ia64/2003-February/004656.html
is attached. The libc part should apply ontop libc cvs and the NPTL
part with NPTL 0.34. To build I used
../libc/configure --with-tls --with-__thread
--with-headers=/usr/src/linux-2.5.64/include
--enable-add-ons=nptl --prefix=/usr CC=gcc-snap
where gcc-snap is the latest 3.3 snapshot [*]. You will obviously
need a kernel that is sufficient to run NPTL and have fsyscall support
enabled.
I can make some debian archives of this if it would help people to
test it. It passes make check (except for known failures) and we here
at Gelato@UNSW will be using it internally, but at the moment all I
would say is "works for me".
Regards,
-i
ianw@gelato.unsw.edu.au
http://www.gelato.unsw.edu.au
[*] I have seen problems with 3.3 snapshots locking up the system and
causing a machine check. I would be interested if anyone using redhat
and their gcc 3.2 with the backported __thread changes sees this
problem.
[-- Attachment #2: libc-cvs-fsyscall.diff --]
[-- Type: text/plain, Size: 5655 bytes --]
? fsyscall-libc.diff
? nptl
? nptl_db
Index: sysdeps/unix/sysv/linux/dl-osinfo.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/dl-osinfo.h,v
retrieving revision 1.13
diff -u -w -r1.13 dl-osinfo.h
--- sysdeps/unix/sysv/linux/dl-osinfo.h 1 Dec 2002 22:14:40 -0000 1.13
+++ sysdeps/unix/sysv/linux/dl-osinfo.h 9 Apr 2003 02:10:20 -0000
@@ -53,9 +53,12 @@
int parts; \
char *cp; \
struct utsname uts; \
+ int uname_err; \
\
- /* Try the uname syscall */ \
- if (__uname (&uts)) \
+ /* use an inline call incase TLS isn't setup and something \
+ like fast syscalls are in use */ \
+ INTERNAL_SYSCALL(uname,uname_err,1,&uts); \
+ if ( uname_err ) \
{ \
/* This was not successful. Now try reading the /proc \
filesystem. */ \
Index: sysdeps/unix/sysv/linux/ia64/clone2.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/ia64/clone2.S,v
retrieving revision 1.7
diff -u -w -r1.7 clone2.S
--- sysdeps/unix/sysv/linux/ia64/clone2.S 13 Mar 2003 04:36:59 -0000 1.7
+++ sysdeps/unix/sysv/linux/ia64/clone2.S 9 Apr 2003 02:10:20 -0000
@@ -25,18 +25,16 @@
/* size_t child_stack_size, int flags, void *arg, */
/* pid_t *parent_tid, void *tls, pid_t *child_tid) */
+#define CHILD p8
+#define PARENT p9
+
ENTRY(__clone2)
- alloc r2=ar.pfs,8,2,6,0
+ .prologue
+ alloc r2=ar.pfs,8,3,6,0
cmp.eq p6,p0=0,in0
mov r8=EINVAL
(p6) br.cond.spnt.few __syscall_error
;;
- flushrs /* This is necessary, since the child */
- /* will be running with the same */
- /* register backing store for a few */
- /* instructions. We need to ensure */
- /* that it will not read or write the */
- /* backing store. */
mov loc0=in0 /* save fn */
mov loc1=in4 /* save arg */
mov out0=in3 /* Flags are first syscall argument. */
@@ -45,14 +43,30 @@
mov out3=in5 /* Parent TID Pointer */
mov out4=in7 /* Child TID Pointer */
mov out5=in6 /* TLS pointer */
- DO_CALL (SYS_ify (clone2))
- cmp.eq p6,p0=-1,r10
+ /*
+ * clone2() is special: the child cannot execute br.ret right after
+ * the system call returns, because it starts out executing on an
+ * empty stack. Because of this, we can't use the new (lightweight)
+ * syscall convention here. Instead, we just fall back on always
+ * using "break".
+ */
+ mov r15=SYS_ify (clone2)
+ /*
+ * The child will start with an empty stack. To avoid unwinding
+ * past invalid memory, we'll pretend now that __clone2() is
+ * the end of the call-chain. This is wrong for the parent, but
+ * only until it returns from clone2() but it's better than the
+ * alternative.
+ */
+ mov b7=r0
+ .prologue
+ .altrp b7
+ .body
+ break __BREAK_SYSCALL
;;
-(p6) br.cond.spnt.few __syscall_error
-
-# define CHILD p6
-# define PARENT p7
cmp.eq CHILD,PARENT=0,r8 /* Are we the child? */
+ cmp.eq p6,p0=-1,r10
+(p6) br.cond.spnt.few __syscall_error
;;
(CHILD) ld8 out1=[loc0],8 /* Retrieve code pointer. */
(CHILD) mov out0=loc1 /* Pass proper argument to fn */
@@ -60,7 +74,6 @@
;;
ld8 gp=[loc0] /* Load function gp. */
mov b6=out1
- ;;
br.call.dptk.few rp=b6 /* Call fn(arg) in the child */
;;
mov out0=r8 /* Argument to _exit */
Index: sysdeps/unix/sysv/linux/ia64/sysdep.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/ia64/sysdep.h,v
retrieving revision 1.14
diff -u -w -r1.14 sysdep.h
--- sysdeps/unix/sysv/linux/ia64/sysdep.h 24 Mar 2003 07:54:28 -0000 1.14
+++ sysdeps/unix/sysv/linux/ia64/sysdep.h 9 Apr 2003 02:10:20 -0000
@@ -24,6 +24,8 @@
#include <sysdeps/unix/sysdep.h>
#include <sysdeps/ia64/sysdep.h>
+#include <tls.h>
+
/* For Linux we can use the system call table in the header file
/usr/include/asm/unistd.h
of the kernel. But these symbols do not follow the SYS_* syntax
@@ -89,9 +91,30 @@
cmp.eq p6,p0=-1,r10; \
(p6) br.cond.spnt.few __syscall_error;
+#if defined HAVE_TLS_SUPPORT && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+
+/* Use the lightweight stub only if (a) we have a suitably modern
+ thread-control block (HAVE_TLS_SUPPORT) and (b) we're not compiling
+ the runtime loader (which might do syscalls before being fully
+ relocated). */
+
+#define DO_CALL(num) \
+ .prologue; \
+ adds r2 = SYSINFO_OFFSET, r13;; \
+ ld8 r2 = [r2]; \
+ .save ar.pfs, r11; \
+ mov r11 = ar.pfs;; \
+ .body; \
+ mov r15 = num; \
+ mov b7 = r2; \
+ br.call.sptk.many b6 = b7;; \
+ .restore sp; \
+ mov ar.pfs = r11
+#else
#define DO_CALL(num) \
mov r15=num; \
break __BREAK_SYSCALL;
+#endif
#undef PSEUDO_END
#define PSEUDO_END(name) .endp C_SYMBOL_NAME(name);
Index: sysdeps/unix/sysv/linux/ia64/vfork.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/ia64/vfork.S,v
retrieving revision 1.4
diff -u -w -r1.4 vfork.S
--- sysdeps/unix/sysv/linux/ia64/vfork.S 31 Dec 2002 20:37:30 -0000 1.4
+++ sysdeps/unix/sysv/linux/ia64/vfork.S 9 Apr 2003 02:10:20 -0000
@@ -34,9 +34,13 @@
mov out0=CLONE_VM+CLONE_VFORK+SIGCHLD
mov out1=0 /* Standard sp value. */
;;
+#if 0
DO_CALL (SYS_ify (clone))
+#else
+ mov r15=SYS_ify(clone)
+ break __BREAK_SYSCALL
+#endif
cmp.eq p6,p0=-1,r10
- ;;
(p6) br.cond.spnt.few __syscall_error
ret
PSEUDO_END(__vfork)
[-- Attachment #3: nptl-0-34-fsyscall.diff --]
[-- Type: text/plain, Size: 6819 bytes --]
Index: allocatestack.c
===================================================================
RCS file: /home/ianw/cvs/nptl/allocatestack.c,v
retrieving revision 1.1.1.3
retrieving revision 1.5
diff -u -r1.1.1.3 -r1.5
Index: descr.h
===================================================================
RCS file: /home/ianw/cvs/nptl/descr.h,v
retrieving revision 1.1.1.3
retrieving revision 1.7
diff -u -r1.1.1.3 -r1.7
--- descr.h 3 Apr 2003 01:02:57 -0000 1.1.1.3
+++ descr.h 7 Apr 2003 02:54:09 -0000 1.7
@@ -62,10 +62,16 @@
#if !TLS_DTV_AT_TP
/* This overlaps the TCB as used for TLS without threads (see tls.h). */
tcbhead_t header;
-#elif TLS_MULTIPLE_THREADS_IN_TCB
+ /* For arch's who don't have room in the TCB */
+#elif (TLS_MULTIPLE_THREADS_IN_TCB || TLS_SYSINFO_IN_TCB)
struct
{
+ #if TLS_MULTIPLE_THREADS_IN_TCB
int multiple_threads;
+ #endif
+ #if TLS_SYSINFO_IN_TCB
+ uintptr_t sysinfo;
+ #endif
} header;
#endif
Index: sysdeps/ia64/tcb-offsets.sym
===================================================================
RCS file: /home/ianw/cvs/nptl/sysdeps/ia64/tcb-offsets.sym,v
retrieving revision 1.1.1.2
retrieving revision 1.5
diff -u -r1.1.1.2 -r1.5
--- sysdeps/ia64/tcb-offsets.sym 31 Mar 2003 00:07:19 -0000 1.1.1.2
+++ sysdeps/ia64/tcb-offsets.sym 7 Apr 2003 02:54:09 -0000 1.5
@@ -2,3 +2,7 @@
#include <tls.h>
MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads) - sizeof (struct pthread)
+
+#ifdef TLS_SYSINFO_IN_TCB
+SYSINFO_OFFSET offsetof (struct pthread, header.sysinfo) - sizeof (struct pthread)
+#endif
Index: sysdeps/ia64/tls.h
===================================================================
RCS file: /home/ianw/cvs/nptl/sysdeps/ia64/tls.h,v
retrieving revision 1.1.1.1
retrieving revision 1.6
diff -u -r1.1.1.1 -r1.6
--- sysdeps/ia64/tls.h 31 Mar 2003 00:06:49 -0000 1.1.1.1
+++ sysdeps/ia64/tls.h 7 Apr 2003 02:54:09 -0000 1.6
@@ -27,6 +27,22 @@
# include <stdlib.h>
# include <list.h>
+/* TLS LAYOUT
+
+ The IA64 ABI specifies that after the thread pointer there is a
+ pointer to the DTV and a private pointer. Consequently in NPTL the
+ thread descriptor is placed directly before the thread pointer (this
+ is significantly cleaner than using indirection with the private
+ pointer).
+
+ [struct pthread][dtv][private][static tls block]
+ tp (r13)----^
+ [ in descr.h ][ tcbhead_t ]
+
+ Note that space is made for the descriptor during TLS setup with the
+ use of TCB_PRE_TCB_SIZE.
+
+*/
/* Type for the dtv. */
typedef union dtv
@@ -35,14 +51,16 @@
void *pointer;
} dtv_t;
-
typedef struct
{
dtv_t *dtv;
void *private;
} tcbhead_t;
+/* As TCB_DTV_AT_TP doesn't allow us more room in the tcbhead defined
+ above, we have extra pointers in our thread descriptor. */
# define TLS_MULTIPLE_THREADS_IN_TCB 1
+# define TLS_SYSINFO_IN_TCB 1
#else /* __ASSEMBLER__ */
# include <tcb-offsets.h>
@@ -100,11 +118,21 @@
# define GET_DTV(descr) \
(((tcbhead_t *) (descr))->dtv)
+/* The room for the thread descriptor is allocated thanks to setting
+ TLS_PRE_TCB_SIZE so we are safe set this here */
+#if NEED_DL_SYSINFO
+# define INIT_SYSINFO \
+ THREAD_SELF->header.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
- operation can cause a failure 'errno' must not be touched. */
-# define TLS_INIT_TP(thrdescr, secondcall) \
- (__thread_self = (thrdescr), NULL)
+ operation can cause a failure 'errno' must not be touched. This
+ should return a string error, but we really can't fail */
+#define TLS_INIT_TP(thrdescr, secondcall) \
+ ( __thread_self = (thrdescr) , INIT_SYSINFO , NULL )
/* Return the address of the dtv for the current thread. */
# define THREAD_DTV() \
Index: sysdeps/pthread/createthread.c
===================================================================
RCS file: /home/ianw/cvs/nptl/sysdeps/pthread/createthread.c,v
retrieving revision 1.1.1.3
retrieving revision 1.4
diff -u -r1.1.1.3 -r1.4
--- sysdeps/pthread/createthread.c 31 Mar 2003 00:13:16 -0000 1.1.1.3
+++ sysdeps/pthread/createthread.c 7 Apr 2003 02:54:09 -0000 1.4
@@ -113,7 +113,7 @@
}
}
-#ifdef NEED_DL_SYSINFO
+#ifdef NEED_DL_SYSINFO
assert (THREAD_GETMEM (THREAD_SELF, header.sysinfo) == pd->header.sysinfo);
#endif
Index: sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
===================================================================
RCS file: sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
diff -N sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sysdeps/unix/sysv/linux/ia64/dl-sysdep.h 31 Mar 2003 00:12:36 -0000 1.1
@@ -0,0 +1,44 @@
+/* System-specific settings for dynamic linker code. IA-64 version.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger <davidm@napali.hpl.hp.com>
+
+ 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
+
+#define NEED_DL_SYSINFO 1
+
+#ifndef __ASSEMBLER__
+/* Don't declare this as a function---we want it's entry-point, not
+ it's function descriptor... */
+extern int _dl_sysinfo_break attribute_hidden;
+# define DL_SYSINFO_DEFAULT ((uintptr_t) &_dl_sysinfo_break)
+# define DL_SYSINFO_IMPLEMENTATION \
+ asm (".text\n\t" \
+ ".hidden _dl_sysinfo_break\n\t" \
+ ".proc _dl_sysinfo_break\n\t" \
+ "_dl_sysinfo_break:\n\t" \
+ ".prologue\n\t" \
+ ".altrp b6\n\t" \
+ ".body\n\t" \
+ "break 0x100000;\n\t" \
+ "br.ret.sptk.many b6;\n\t" \
+ ".endp _dl_sysinfo_break");
+#endif
+
+#endif /* dl-sysdep.h */
Index: sysdeps/unix/sysv/linux/ia64/lowlevellock.h
===================================================================
RCS file: /home/ianw/cvs/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h,v
retrieving revision 1.1.1.4
retrieving revision 1.2
diff -u -r1.1.1.4 -r1.2
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2003-04-09 2:38 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-04-09 2:38 [Linux-ia64] glibc fsyscall patch Ian Wienand
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.