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] glibc ia64 -fstack-protector support


Hi!

This patch adds support for ia64 TLS stack canary (at $r13-8).
ATM only far smaller patch would be enough, since there is 8 byte
padding at the end of struct pthread on ia64, but that doesn't have
to last forever.  Tested on ia64 both with just this patch and
with also addition of 64-bit dummy field before struct pthread's
res field (so that there is no padding and therefore we need to
grow TLS_PRE_TCB_SIZE by 8 bytes).

I have also included the fix reported by Ulrich Weigand for s390x/s390
STACK_CHK_GUARD macro.

2005-07-05  Jakub Jelinek  <jakub@redhat.com>

	* elf/stackguard-macros.h (STACK_CHK_GUARD): Fix s390/s390x definition.
	Reported by Ulrich Weigand <uweigand@de.ibm.com>.

	* elf/stackguard-macros.h (STACK_CHK_GUARD): Add ia64 definition.
nptl/
	* descr.h (PTHREAD_STRUCT_END_PADDING): Define.
	* sysdeps/ia64/tls.h (TLS_PRE_TCB_SIZE): If PTHREAD_STRUCT_END_PADDING
	is smaller than 8 bytes, increase TLS_PRE_TCB_SIZE by 16 bytes.
	(THREAD_SYSINFO, THREAD_SELF, DB_THREAD_SELF): Don't assume
	TLS_PRE_TCB_SIZE is sizeof (struct pthread).
	(THREAD_SET_STACK_GUARD, THREAD_COPY_STACK_GUARD): Define.
	* sysdeps/ia64/tcb-offsets.sym (PID, TID, MULTIPLE_THREADS_OFFSET):
	Use TLS_PRE_TCB_SIZE instead of sizeof (struct pthread).
	* sysdeps/unix/sysv/linux/ia64/createthread.c (TLS_VALUE): Don't
	assume TLS_PRE_TCB_SIZE is sizeof (struct pthread).

--- libc/elf/stackguard-macros.h.jj	2005-06-26 20:07:28.000000000 +0200
+++ libc/elf/stackguard-macros.h	2005-07-05 10:20:14.000000000 +0200
@@ -20,10 +20,13 @@
   ({ uintptr_t x; asm ("ld [%%g7+0x14], %0" : "=r" (x)); x; })
 #elif defined __s390x__
 # define STACK_CHK_GUARD \
-  ({ uintptr_t x; asm ("ear %0,%a0; sllg %0,%0,32; ear %0,%a1; lg %0,0x28(%0)" : "=r" (x)); x; })
+  ({ uintptr_t x; asm ("ear %0,%%a0; sllg %0,%0,32; ear %0,%%a1; lg %0,0x28(%0)" : "=a" (x)); x; })
 #elif defined __s390__
 # define STACK_CHK_GUARD \
-  ({ uintptr_t x; asm ("ear %0,%%a0; l %0,0x14(%0)" : "=r" (x)); x; })
+  ({ uintptr_t x; asm ("ear %0,%%a0; l %0,0x14(%0)" : "=a" (x)); x; })
+#elif defined __ia64__
+# define STACK_CHK_GUARD \
+  ({ uintptr_t x; asm ("adds %0 = -8, r13;; ld8 %0 = [%0]" : "=r" (x)); x; })
 #else
 extern uintptr_t __stack_chk_guard;
 # define STACK_CHK_GUARD __stack_chk_guard
--- libc/nptl/descr.h.jj	2004-11-12 13:57:44.000000000 +0100
+++ libc/nptl/descr.h	2005-07-04 11:19:30.000000000 +0200
@@ -254,6 +254,13 @@ struct pthread
 
   /* Resolver state.  */
   struct __res_state res;
+
+  /* If you add fields after the res field above, please adjust
+     the following macro.  */
+#define PTHREAD_STRUCT_END_PADDING \
+  (sizeof (struct pthread) - offsetof (struct pthread, res) \
+   - sizeof (((struct pthread *) 0)->res))
+
 } __attribute ((aligned (TCB_ALIGNMENT)));
 
 
--- libc/nptl/sysdeps/ia64/tls.h.jj	2005-01-08 16:50:23.000000000 +0100
+++ libc/nptl/sysdeps/ia64/tls.h	2005-07-04 11:53:18.000000000 +0200
@@ -80,8 +80,15 @@ register struct pthread *__thread_self _
 /* This is the size of the TCB.  */
 # define TLS_TCB_SIZE sizeof (tcbhead_t)
 
-/* This is the size we need before TCB.  */
-# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
+/* This is the size we need before TCB.
+   If there is not any room for uintptr_t stack_guard in struct pthread's
+   final padding, we need to put struct pthread 16 byte slower.  */
+# define TLS_PRE_TCB_SIZE \
+  (sizeof (struct pthread)					\
+   + (PTHREAD_STRUCT_END_PADDING < sizeof (uintptr_t)		\
+      ? ((sizeof (uintptr_t) + __alignof__ (struct pthread) - 1)\
+	 & ~(__alignof__ (struct pthread) - 1))			\
+      : 0))
 
 /* Alignment requirements for the TCB.  */
 # define TLS_TCB_ALIGN __alignof__ (struct pthread)
@@ -106,7 +113,8 @@ register struct pthread *__thread_self _
   (((tcbhead_t *) (descr))->dtv)
 
 #define THREAD_SELF_SYSINFO	(((tcbhead_t *) __thread_self)->private)
-#define THREAD_SYSINFO(pd)	(((tcbhead_t *) ((pd) + 1))->private)
+#define THREAD_SYSINFO(pd) \
+  (((tcbhead_t *) ((char *) (pd) + TLS_PRE_TCB_SIZE))->private)
 
 #if defined NEED_DL_SYSINFO
 # define INIT_SYSINFO   THREAD_SELF_SYSINFO = (void *) GLRO(dl_sysinfo)
@@ -125,10 +133,11 @@ register struct pthread *__thread_self _
   (((tcbhead_t *)__thread_self)->dtv)
 
 /* Return the thread descriptor for the current thread.  */
-# define THREAD_SELF (__thread_self - 1)
+# define THREAD_SELF \
+  ((struct pthread *) ((char *) __thread_self - TLS_PRE_TCB_SIZE))
 
 /* Magic for libthread_db to know how to do THREAD_SELF.  */
-# define DB_THREAD_SELF REGISTER (64, 64, 13 * 8, -sizeof (struct pthread))
+# define DB_THREAD_SELF REGISTER (64, 64, 13 * 8, -TLS_PRE_TCB_SIZE)
 
 /* Access to data in the thread descriptor is easy.  */
 #define THREAD_GETMEM(descr, member) \
@@ -140,6 +149,13 @@ register struct pthread *__thread_self _
 #define THREAD_SETMEM_NC(descr, member, idx, value) \
   descr->member[idx] = (value)
 
+/* Set the stack guard field in TCB head.  */
+#define THREAD_SET_STACK_GUARD(value) \
+  (((uintptr_t *) __thread_self)[-1] = (value))
+#define THREAD_COPY_STACK_GUARD(descr) \
+  (((uintptr_t *) ((char *) (descr) + TLS_PRE_TCB_SIZE))[-1] \
+   = ((uintptr_t *) __thread_self)[-1])
+
 #endif /* __ASSEMBLER__ */
 
 #endif	/* tls.h */
--- libc/nptl/sysdeps/ia64/tcb-offsets.sym.jj	2004-12-13 09:36:18.000000000 +0100
+++ libc/nptl/sysdeps/ia64/tcb-offsets.sym	2005-07-04 23:12:08.000000000 +0200
@@ -1,7 +1,7 @@
 #include <sysdep.h>
 #include <tls.h>
 
-PID			offsetof (struct pthread, pid) - sizeof (struct pthread)
-TID			offsetof (struct pthread, tid) - sizeof (struct pthread)
-MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads) - sizeof (struct pthread)
+PID			offsetof (struct pthread, pid) - TLS_PRE_TCB_SIZE
+TID			offsetof (struct pthread, tid) - TLS_PRE_TCB_SIZE
+MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads) - TLS_PRE_TCB_SIZE
 SYSINFO_OFFSET		offsetof (tcbhead_t, private)
--- libc/nptl/sysdeps/unix/sysv/linux/ia64/createthread.c.jj	2003-03-11 04:20:41.000000000 -0500
+++ libc/nptl/sysdeps/unix/sysv/linux/ia64/createthread.c	2005-07-05 08:09:38.928248675 -0400
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>.
 
@@ -18,7 +18,7 @@
    02111-1307 USA.  */
 
 /* Value passed to 'clone' for initialization of the thread register.  */
-#define TLS_VALUE (pd + 1)
+#define TLS_VALUE ((char *) pd + TLS_PRE_TCB_SIZE)
 
 #define ARCH_CLONE __clone2
 

	Jakub


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