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] |
Below is a draft patch to add support to libc for the new syscall stub I'd like to start using on ia64 linux. The main change here is that the syscall stub will do an indirect call via a "sysinfo" pointer picked up from the thread-control-block. By default, "sysinfo" points to a _dl_sysinfo_break(), which does an old-style "break 0x100000" syscall. With newer kernels, this will get redefined via AT_SYSINFO to an entry-point in the kernel's gate page, which does a light-weight entry into the kernel. Since it is extremely unpleasant to have to syscall stubs change, I'd like the tp-offset of the "sysinfo" pointer to be set in stone. The ia64 ABI reserves the positive offsets off the thread-pointer for its own purposes, so I'd like to propose an offset of -8. In the patch below, I did this by moving the "p_header" in _pthread_desc_struct to the end of the structure (if TLS_TCB_AT_TP is not defined). Most of the other changes should be pretty obvious. One rather ugly hack though is that in libc-start.c, I had to reverse the order of DL_SYSDEP_OSCHEC() and __pthread_initialize_minimal(): the former calls uname() and with the new syscall stub, the thread-pointer needs to be valid before a system call can be invoked. If this isn't acceptable, suggestions for improvements would be welcome. Thanks, --david PS: No ChangeLog since I just want to get feedback at this point---the patch isn't ready for prime-time yet. PPS: Relative to what was discussed on the linux-ia64 mailing list, I changed the syscall stub slightly: r9 got replaced by r11, because some system calls (e.g., pipe()) use r9 to return a second return value. r11 should be safe that way. Index: linuxthreads/descr.h =================================================================== RCS file: /cvs/glibc/libc/linuxthreads/descr.h,v retrieving revision 1.8 diff -u -r1.8 descr.h --- linuxthreads/descr.h 28 Dec 2002 10:14:16 -0000 1.8 +++ linuxthreads/descr.h 14 Jan 2003 07:09:56 -0000 @@ -109,6 +109,7 @@ struct _pthread_descr_struct { /* XXX Remove this union for IA-64 style TLS module */ +#if TLS_TCB_AT_TP union { struct { void *tcb; /* Pointer to the TCB. This is not always @@ -122,6 +123,9 @@ } data; void *__padding[16]; } p_header; +#else + /* New elements must be added at the beginning. */ +#endif pthread_descr p_nextlive, p_prevlive; /* Double chaining of active threads */ pthread_descr p_nextwaiting; /* Next element in the queue holding the thr */ @@ -180,7 +184,23 @@ #endif size_t p_alloca_cutoff; /* Maximum size which should be allocated using alloca() instead of malloc(). */ +#if TLS_TCB_AT_TP /* New elements must be added at the end. */ +#else + union { + struct { + void *reserved[11]; /* reserve for future use */ + void *tcb; /* XXX do we really need this? */ + union dtv *dtvp; /* XXX do we really need this? */ + pthread_descr self; /* XXX do we really need this? */ + int multiple_threads; +#ifdef NEED_DL_SYSINFO + uintptr_t sysinfo; +#endif + } data; + void *__padding[16]; + } p_header __attribute__ ((aligned(32))); +#endif } __attribute__ ((aligned(32))); /* We need to align the structure so that doubles are aligned properly. This is 8 bytes on MIPS and 16 bytes on MIPS64. Index: linuxthreads/sysdeps/ia64/tcb-offsets.sym =================================================================== RCS file: /cvs/glibc/libc/linuxthreads/sysdeps/ia64/tcb-offsets.sym,v retrieving revision 1.2 diff -u -r1.2 tcb-offsets.sym --- linuxthreads/sysdeps/ia64/tcb-offsets.sym 12 Jan 2003 08:39:41 -0000 1.2 +++ linuxthreads/sysdeps/ia64/tcb-offsets.sym 14 Jan 2003 07:09:56 -0000 @@ -2,3 +2,9 @@ #include <tls.h> MULTIPLE_THREADS_OFFSET offsetof (struct _pthread_descr_struct, p_header.data.multiple_threads) - sizeof (struct _pthread_descr_struct) + +#ifdef HAVE_TLS_SUPPORT + +SYSINFO_OFFSET offsetof (struct _pthread_descr_struct, p_header.data.sysinfo) - sizeof (struct _pthread_descr_struct) + +#endif Index: linuxthreads/sysdeps/ia64/tls.h =================================================================== RCS file: /cvs/glibc/libc/linuxthreads/sysdeps/ia64/tls.h,v retrieving revision 1.3 diff -u -r1.3 tls.h --- linuxthreads/sysdeps/ia64/tls.h 12 Jan 2003 08:38:42 -0000 1.3 +++ linuxthreads/sysdeps/ia64/tls.h 14 Jan 2003 07:09:56 -0000 @@ -20,10 +20,13 @@ #ifndef _TLS_H #define _TLS_H +#include <dl-sysdep.h> + #ifndef __ASSEMBLER__ # include <pt-machine.h> # include <stddef.h> +# include <stdint.h> /* Type for the dtv. */ typedef union dtv @@ -83,8 +86,10 @@ /* 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(tcbp, secondcall) \ - (__thread_self = (tcbp), NULL) +# define TLS_INIT_TP(tcbp, secondcall) \ + (__thread_self = (tcbp), \ + THREAD_SELF->p_header.data.sysinfo = GL(dl_sysinfo), \ + NULL) /* Return the address of the dtv for the current thread. */ # define THREAD_DTV() \ @@ -114,6 +119,7 @@ static struct _pthread_descr_struct nontls_init_tp \ = { .p_header.data.multiple_threads = 0 }; \ __thread_self = ((__typeof (__thread_self)) &nontls_init_tp) + 1; \ + THREAD_SELF->p_header.data.sysinfo = GL(dl_sysinfo); \ } while (0) #endif Index: linuxthreads/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h =================================================================== RCS file: linuxthreads/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h diff -N linuxthreads/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ linuxthreads/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h 14 Jan 2003 07:09:56 -0000 @@ -0,0 +1,43 @@ +/* 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. + + 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 + +#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/generic/libc-start.c =================================================================== RCS file: /cvs/glibc/libc/sysdeps/generic/libc-start.c,v retrieving revision 1.35 diff -u -r1.35 libc-start.c --- sysdeps/generic/libc-start.c 28 Dec 2002 09:14:52 -0000 1.35 +++ sysdeps/generic/libc-start.c 14 Jan 2003 07:09:56 -0000 @@ -83,14 +83,6 @@ ++auxvec; _dl_aux_init ((ElfW(auxv_t) *) auxvec); # endif -# ifdef DL_SYSDEP_OSCHECK - if (!__libc_multiple_libcs) - { - /* This needs to run to initiliaze _dl_osversion before TLS - setup might check it. */ - DL_SYSDEP_OSCHECK (__libc_fatal); - } -# endif /* Initialize the thread library at least a bit since the libgcc functions are using thread functions if these are available and @@ -101,6 +93,15 @@ if (__pthread_initialize_minimal) # endif __pthread_initialize_minimal (); + +# ifdef DL_SYSDEP_OSCHECK + if (!__libc_multiple_libcs) + { + /* This needs to run to initiliaze _dl_osversion before TLS + setup might check it. */ + DL_SYSDEP_OSCHECK (__libc_fatal); + } +# endif /* Some security at this point. Prevent starting a SUID binary where the standard file descriptors are not opened. We have to do this Index: sysdeps/unix/sysv/linux/ia64/sysdep.h =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/ia64/sysdep.h,v retrieving revision 1.10 diff -u -r1.10 sysdep.h --- sysdeps/unix/sysv/linux/ia64/sysdep.h 9 Jan 2003 04:09:25 -0000 1.10 +++ sysdeps/unix/sysv/linux/ia64/sysdep.h 14 Jan 2003 07:09:57 -0000 @@ -23,6 +23,7 @@ #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 @@ -89,9 +90,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 Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |