From: Ian Wienand <ianw@gelato.unsw.edu.au>
To: linux-ia64@vger.kernel.org
Subject: [Linux-ia64] glibc fsyscall patch
Date: Wed, 09 Apr 2003 02:38:45 +0000 [thread overview]
Message-ID: <marc-linux-ia64-105590723705444@msgid-missing> (raw)
[-- 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
reply other threads:[~2003-04-09 2:38 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=marc-linux-ia64-105590723705444@msgid-missing \
--to=ianw@gelato.unsw.edu.au \
--cc=linux-ia64@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox