]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Update.
authorUlrich Drepper <drepper@redhat.com>
Wed, 24 Sep 2003 03:22:56 +0000 (03:22 +0000)
committerUlrich Drepper <drepper@redhat.com>
Wed, 24 Sep 2003 03:22:56 +0000 (03:22 +0000)
2003-09-23  Ulrich Drepper  <drepper@redhat.com>

* sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions [libc]
(GLIBC_2.3.3): Add setcontext, getcontext, swapcontext, and
makecontext.
* sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h: Correct change
for include Altivec support for PPC32.  It was not compatible.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.h: Adjust
offsets for ucontext_t change.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S: Adjust
for ucontext_t change.  Add compatibility code.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S: Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S: Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S: Likewise.
Patch by Paul Mackerras <paulus@samba.org>.

2003-02-25  Randolph Chung  <tausq@debian.org>

* sysdeps/hppa/Makefile: Include compat code in build.
* sysdeps/hppa/libgcc-compat.c: New file.
* sysdeps/hppa/Dist: Add libgcc-compat.c.
* sysdeps/hppa/Versions [GLIBC_2.2]: Add __clz_tab.

17 files changed:
ChangeLog
nptl/ChangeLog
nptl/Makefile
nptl/allocatestack.c
nptl/init.c
nptl/pthreadP.h
sysdeps/hppa/Dist
sysdeps/hppa/Makefile
sysdeps/hppa/Versions
sysdeps/hppa/libgcc-compat.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions
sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S
sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S
sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S
sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S
sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.h
sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h

index 1c659e8b4632733907dc7092ca81c7cdecd13719..028de322fa8305c903abed508299782221a63b3c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2003-09-23  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions [libc]
+       (GLIBC_2.3.3): Add setcontext, getcontext, swapcontext, and
+       makecontext.
+       * sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h: Correct change
+       for include Altivec support for PPC32.  It was not compatible.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.h: Adjust
+       offsets for ucontext_t change.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S: Adjust
+       for ucontext_t change.  Add compatibility code.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S: Likewise.
+       Patch by Paul Mackerras <paulus@samba.org>.
+
+2003-02-25  Randolph Chung  <tausq@debian.org>
+
+       * sysdeps/hppa/Makefile: Include compat code in build.
+       * sysdeps/hppa/libgcc-compat.c: New file.
+       * sysdeps/hppa/Dist: Add libgcc-compat.c.
+       * sysdeps/hppa/Versions [GLIBC_2.2]: Add __clz_tab.
+
 2003-09-23  Roland McGrath  <roland@redhat.com>
 
        * elf/rtld.c (dl_main): In rtld_is_main case, reinitialize
index 00bfbf9ad8d30fd3231b0980f853e21fa6be66db..031c9e08cd6c9cd7c1607cf3fc0f1bc0a0d3f4f1 100644 (file)
@@ -1,3 +1,21 @@
+2003-09-23  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (tests): Only add tst-execstack if have-z-execstack is yes.
+
+2003-09-23  Roland McGrath  <roland@redhat.com>
+
+       * tst-execstack.c: New file.
+       * Makefile (tests): Add it.
+       ($(objpfx)tst-execstack, $(objpfx)tst-execstack.out): New targets.
+       (LDFLAGS-tst-execstack): New variable.
+
+       * allocatestack.c (allocate_stack): Use GL(dl_stack_flags) to decide
+       whether to use PROT_EXEC for stack mmap.
+       (__make_stacks_executable): New function.
+       * pthreadP.h: Declare it.
+       * init.c (__pthread_initialize_minimal_internal): Set
+       GL(dl_make_stack_executable_hook) to that.
+
 2003-09-22  Ulrich Drepper  <drepper@redhat.com>
 
        * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Adjust for latest
index d592137caf94cb775126ccf05a410fa777bdb031..cf438bbdb687ebf9673653765a5bcc8a889394bb 100644 (file)
@@ -253,6 +253,9 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \
 endif
 ifeq ($(build-shared),yes)
 tests += tst-atfork2 tst-tls3 tst-tls4 tst-tls5 tst-_res1
+ifeq ($(have-z-execstack),yes)
+tests += tst-execstack
+endif
 endif
 
 modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
@@ -540,3 +543,7 @@ endif
 endif
 
 tst-exec4-ARGS = $(built-program-cmd)
+
+$(objpfx)tst-execstack: $(libdl)
+$(objpfx)tst-execstack.out: $(elf-objpfx)tst-execstack-mod.so
+LDFLAGS-tst-execstack = -Wl,-z,noexecstack
index 6ada1fe1381de104153c0627e27f09fe5ad02caa..dc501650b8629eda4502f2016016f09106cfb526 100644 (file)
@@ -351,11 +351,12 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
     }
   else
     {
-      /* Allocate some anonymous memory.  If possible use the
-        cache.  */
+      /* Allocate some anonymous memory.  If possible use the cache.  */
       size_t guardsize;
       size_t reqsize;
       void *mem;
+      const int prot = (PROT_READ | PROT_WRITE
+                       | ((GL(dl_stack_flags) & PF_X) ? PROT_EXEC : 0));
 
 #if COLORING_INCREMENT != 0
       /* Add one more page for stack coloring.  Don't do it for stacks
@@ -392,7 +393,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
            size += pagesize_m1 + 1;
 #endif
 
-         mem = mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
+         mem = mmap (NULL, size, prot,
                      MAP_PRIVATE | MAP_ANONYMOUS | ARCH_MAP_FLAGS, -1, 0);
 
          if (__builtin_expect (mem == MAP_FAILED, 0))
@@ -546,17 +547,16 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
          char *oldguard = mem + (((size - pd->guardsize) / 2) & ~pagesize_m1);
 
          if (oldguard < guard
-             && mprotect (oldguard, guard - oldguard,
-                          PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
+             && mprotect (oldguard, guard - oldguard, prot) != 0)
            goto mprot_error;
 
          if (mprotect (guard + guardsize,
                        oldguard + pd->guardsize - guard - guardsize,
-                       PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
+                       prot) != 0)
            goto mprot_error;
 #else
          if (mprotect ((char *) mem + guardsize, pd->guardsize - guardsize,
-                       PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
+                       prot) != 0)
            goto mprot_error;
 #endif
 
@@ -616,6 +616,45 @@ __deallocate_stack (struct pthread *pd)
 }
 
 
+int
+internal_function
+__make_stacks_executable (void)
+{
+#ifdef NEED_SEPARATE_REGISTER_STACK
+  const size_t pagemask = ~(__getpagesize () - 1);
+#endif
+
+  lll_lock (stack_cache_lock);
+
+  int err = 0;
+  list_t *runp;
+  list_for_each (runp, &stack_used)
+    {
+      struct pthread *const pd = list_entry (runp, struct pthread, list);
+#ifdef NEED_SEPARATE_REGISTER_STACK
+      void *stack = (pd->stackblock
+                    + (((((pd->stackblock_size - pd->guardsize) / 2)
+                         & pagemask) + pd->guardsize) & pagemask));
+      size_t len = pd->stackblock + pd->stackblock_size - stack;
+#else
+      void *stack = pd->stackblock + pd->guardsize;
+      size_t len = pd->stackblock_size - pd->guardsize;
+#endif
+      if (mprotect (stack, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
+       {
+         err = errno;
+         break;
+       }
+    }
+
+  lll_unlock (stack_cache_lock);
+
+  _dl_make_stack_executable ();
+
+  return err;
+}
+
+
 /* In case of a fork() call the memory allocation in the child will be
    the same but only one thread is running.  All stacks except that of
    the one running thread are not used anymore.  We have to recycle
index 7b8b2b0c54fd5ce25da7a969a96e73f89fd3d981..36b65425f54319bc2284602a735e49e230e906ea 100644 (file)
@@ -283,6 +283,8 @@ __pthread_initialize_minimal_internal (void)
   GL(dl_load_lock).mutex.__data.__count = 0;
   while (rtld_lock_count-- > 0)
     INTUSE (__pthread_mutex_lock) (&GL(dl_load_lock).mutex);
+
+  GL(dl_make_stack_executable_hook) = &__make_stacks_executable;
 #endif
 
   GL(dl_init_static_tls) = &__pthread_init_static_tls;
index 4159ea6862f01e2ebb6c44bfcd1c018020d6511d..986e3788fb7a81a580791f5019635ec94fb12e0b 100644 (file)
@@ -215,6 +215,9 @@ extern void __deallocate_stack (struct pthread *pd)
    function also re-initializes the lock for the stack cache.  */
 extern void __reclaim_stacks (void) attribute_hidden;
 
+/* Make all threads's stacks executable.  */
+int __make_stacks_executable (void) internal_function attribute_hidden;
+
 /* longjmp handling.  */
 extern void __pthread_cleanup_upto (__jmp_buf target, char *targetframe);
 #if defined NOT_IN_libc && defined IS_IN_libpthread
index 9fc1de291a507e1bff5edee492dc0349c6a12434..e26e411bc5ac51b93fed5630aba1ac28ef563c2f 100644 (file)
@@ -1,2 +1,3 @@
+libgcc-compat.c
 dl-symaddr.c
 dl-fptr.c
index 170bd07ab3ca3315adbb3dddaaec4ead09497332..68651f64977e286649b21292c08ae2325a36ab35 100644 (file)
@@ -31,3 +31,14 @@ CFLAGS-rtld.c += -mdisable-fpregs
 dl-routines += dl-symaddr dl-fptr
 rtld-routines += dl-symaddr dl-fptr
 endif
+
+ifeq ($(subdir),csu)
+ifeq (yes,$(build-shared))
+# Compatibility
+ifeq (yes,$(have-protected))
+CPPFLAGS-libgcc-compat.c = -DHAVE_DOT_HIDDEN
+endif
+sysdep_routines += libgcc-compat
+shared-only-routines += libgcc-compat
+endif
+endif
index 909d50bbf5b5454d1b26f0b2283f9c0f213f8fd5..2ae3cbdf1774a588b29989dfc468a08b2613837d 100644 (file)
@@ -5,3 +5,8 @@ ld {
     _dl_function_address;
   }
 }
+libc {
+  GLIBC_2.2 {
+    __clz_tab;
+  }
+}
diff --git a/sysdeps/hppa/libgcc-compat.c b/sysdeps/hppa/libgcc-compat.c
new file mode 100644 (file)
index 0000000..2957eba
--- /dev/null
@@ -0,0 +1,43 @@
+/* pre-.hidden libgcc compatibility
+   Copyright (C) 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Randolph Chung
+
+   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.  */
+
+
+#include <stdint.h>
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_6)
+
+symbol_version (__clz_tab_internal, __clz_tab, GLIBC_2.2);
+
+typedef unsigned int UQItype  __attribute__ ((mode (QI)));
+
+const UQItype __clz_tab_internal[] =
+{
+  0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+};
+
+#endif
index 92158ee1b5780702a90ff25ad2de9da4e528731b..d667eadbcefbcaeba5954967cb2bbb24f4997836 100644 (file)
@@ -22,5 +22,6 @@ libc {
   }
   GLIBC_2.3.3 {
     posix_fadvise64; posix_fallocate64;
+    setcontext; getcontext; swapcontext; makecontext;
   }
 }
index 9405d12cfbf4bfc84cc3f7f0976fbb5c1c5b67b0..3b1b3b9449998905eeb5a5ab194b3ff0a2a1fe58 100644 (file)
    02111-1307 USA.  */
 
 #include <sysdep.h>
+#include <shlib-compat.h>
 
 #define __ASSEMBLY__
 #include <asm/ptrace.h>
 #include "ucontext_i.h"
 
 ENTRY(__getcontext)
+       /*
+        * Since we are not attempting to save the altivec registers,
+        * there is no need to get the register storage space
+        * aligned on a 16-byte boundary.
+        */
+       addi    r3,r3,_UC_REG_SPACE
+       stw     r3,_UC_REGS_PTR - _UC_REG_SPACE(r3)
        stw     r0,_UC_GREGS+(PT_R0*4)(r3)
        stw     r1,_UC_GREGS+(PT_R1*4)(r3)
        mflr    r0
@@ -112,7 +120,7 @@ ENTRY(__getcontext)
        stfd    fp31,_UC_FREGS+(31*8)(r3)
        stfd    fp0,_UC_FREGS+(32*8)(r3)
 
-       addi    r5,r3,_UC_SIGMASK
+       addi    r5,r3,_UC_SIGMASK - _UC_REG_SPACE
        li      r4,0
        li      r3,SIG_BLOCK
        bl      JUMPTARGET(sigprocmask)
@@ -123,4 +131,18 @@ ENTRY(__getcontext)
        blr
 PSEUDO_END(__getcontext)
 
-weak_alias(__getcontext, getcontext)
+versioned_symbol (libc, __getcontext, getcontext, GLIBC_2_3_3)
+
+#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3_3)
+
+#define _ERRNO_H       1
+#include <bits/errno.h>
+
+ENTRY (__getcontext_stub)
+       li      r3,ENOSYS
+       b       JUMPTARGET(__syscall_error)
+       END (__getcontext_stub)
+
+compat_symbol (libc, __getcontext_stub, getcontext, GLIBC_2_1)
+
+#endif
index b875aa5de0c17d737077db90be78dfce598a230d..9cb0b874f5065e04052bac481f4dbc283d3ccb4e 100644 (file)
@@ -18,6 +18,7 @@
    02111-1307 USA.  */
 
 #include <sysdep.h>
+#include <shlib-compat.h>
 
 #define __ASSEMBLY__
 #include <asm/ptrace.h>
 
 ENTRY(__makecontext)
        /* Set up the first 7 args to the function in its registers */
-       stw     r6,_UC_GREGS+(PT_R3*4)(r3)
-       stw     r7,_UC_GREGS+(PT_R4*4)(r3)
-       stw     r8,_UC_GREGS+(PT_R5*4)(r3)
-       stw     r9,_UC_GREGS+(PT_R6*4)(r3)
-       stw     r10,_UC_GREGS+(PT_R7*4)(r3)
+       addi    r11,r3,_UC_REG_SPACE
+       stw     r11,_UC_REGS_PTR(r3)
+       stw     r6,_UC_GREGS+(PT_R3*4)(r11)
+       stw     r7,_UC_GREGS+(PT_R4*4)(r11)
+       stw     r8,_UC_GREGS+(PT_R5*4)(r11)
+       stw     r9,_UC_GREGS+(PT_R6*4)(r11)
+       stw     r10,_UC_GREGS+(PT_R7*4)(r11)
        lwz     r8,8(r1)
        lwz     r9,12(r1)
-       stw     r8,_UC_GREGS+(PT_R8*4)(r3)
-       stw     r9,_UC_GREGS+(PT_R9*4)(r3)
+       stw     r8,_UC_GREGS+(PT_R8*4)(r11)
+       stw     r9,_UC_GREGS+(PT_R9*4)(r11)
 
        /* Set the NIP to the start of the function */
-       stw     r4,_UC_GREGS+(PT_NIP*4)(r3)
+       stw     r4,_UC_GREGS+(PT_NIP*4)(r11)
 
        /* Set the function's r31 to ucp->uc_link for the exitcode below. */
        lwz     r7,_UC_LINK(r3)
-       stw     r7,_UC_GREGS+(PT_R31*4)(r3)
+       stw     r7,_UC_GREGS+(PT_R31*4)(r11)
 
        /* Set the function's LR to point to the exitcode below. */
 #ifdef PIC
@@ -53,7 +56,7 @@ ENTRY(__makecontext)
        lis     r6,L(exitcode)@ha
        addi    r6,r6,L(exitcode)@l
 #endif
-       stw     r6,_UC_GREGS+(PT_LNK*4)(r3)
+       stw     r6,_UC_GREGS+(PT_LNK*4)(r11)
 
        /*
         * Set up the stack frame for the function.
@@ -71,7 +74,7 @@ ENTRY(__makecontext)
        cmpwi   r5,8
        blt     2f              /* less than 8 args is easy */
        lwz     r10,16(r1)
-       stw     r10,_UC_GREGS+(PT_R10*4)(r3)
+       stw     r10,_UC_GREGS+(PT_R10*4)(r11)
        beq     2f              /* if exactly 8 args */
        subi    r9,r5,3
        subi    r5,r5,8
@@ -83,7 +86,7 @@ ENTRY(__makecontext)
 3:     lwzu    r10,4(r6)
        stwu    r10,4(r8)
        bdnz    3b
-2:     stw     r7,_UC_GREGS+(PT_R1*4)(r3)
+2:     stw     r7,_UC_GREGS+(PT_R1*4)(r11)
        li      r6,0
        stw     r6,0(r7)
 
@@ -102,4 +105,19 @@ L(exitcode):
        b       4b
 
 END(__makecontext)
-weak_alias(__makecontext, makecontext)
+
+versioned_symbol (libc, __makecontext, makecontext, GLIBC_2_3_3)
+
+#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3_3)
+
+#define _ERRNO_H       1
+#include <bits/errno.h>
+
+ENTRY (__makecontext_stub)
+       li      r3,ENOSYS
+       b       JUMPTARGET(__syscall_error)
+       END (__makecontext_stub)
+
+compat_symbol (libc, __makecontext_stub, makecontext, GLIBC_2_1)
+
+#endif
index 1539b40f018fbbd0a3472a0419b924e72731bf15..deb946137df211fe93eba9baf86f5e3dc82d30d3 100644 (file)
@@ -18,6 +18,7 @@
    02111-1307 USA.  */
 
 #include <sysdep.h>
+#include <shlib-compat.h>
 
 #define __ASSEMBLY__
 #include <asm/ptrace.h>
@@ -28,7 +29,7 @@ ENTRY(__setcontext)
        stwu    r1,-16(r1)
        stw     r0,20(r1)
        stw     r31,12(r1)
-       mr      r31,r3
+       lwz     r31,_UC_REGS_PTR(r3)
 
        /*
         * If this ucontext refers to the point where we were interrupted
@@ -144,6 +145,20 @@ L(do_sigret):
        sc
        /* NOTREACHED */
 
-PSEUDO_END(__setcontext)
+PSEUDO_END (__setcontext)
 
-weak_alias(__setcontext, setcontext)
+versioned_symbol (libc, __setcontext, setcontext, GLIBC_2_3_3)
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_3)
+
+#define _ERRNO_H       1
+#include <bits/errno.h>
+
+ENTRY (__setcontext_stub)
+       li      r3,ENOSYS
+       b       JUMPTARGET(__syscall_error)
+       END (__setcontext_stub)
+
+compat_symbol (libc, __setcontext_stub, setcontext, GLIBC_2_0)
+
+#endif
index 88cf0dae8f150c2fd6bafa054cda2d8573f3fc86..fac68029599fab57a7fa0512f257d22581163bde 100644 (file)
@@ -18,6 +18,7 @@
    02111-1307 USA.  */
 
 #include <sysdep.h>
+#include <shlib-compat.h>
 
 #define __ASSEMBLY__
 #include <asm/ptrace.h>
@@ -25,6 +26,8 @@
 
 ENTRY(__swapcontext)
        /* Save the current context */
+       addi    r3,r3,_UC_REG_SPACE
+       stw     r3,_UC_REGS_PTR - _UC_REG_SPACE(r3)
        stw     r0,_UC_GREGS+(PT_R0*4)(r3)
        stw     r1,_UC_GREGS+(PT_R1*4)(r3)
        mflr    r0
@@ -115,7 +118,7 @@ ENTRY(__swapcontext)
        stfd    fp31,_UC_FREGS+(31*8)(r3)
        stfd    fp0,_UC_FREGS+(32*8)(r3)
 
-       addi    r5,r3,_UC_SIGMASK
+       addi    r5,r3,_UC_SIGMASK - _UC_REG_SPACE
        addi    r4,r4,_UC_SIGMASK
        li      r3,SIG_SETMASK
        bl      JUMPTARGET(sigprocmask)
@@ -133,6 +136,8 @@ ENTRY(__swapcontext)
         * r0, xer, ctr.  We don't restore r2 since it will be used as
         * the TLS pointer.
         */
+       mr      r4,r31
+       lwz     r31,_UC_REGS_PTR(r31)
        lwz     r0,_UC_GREGS+(PT_MSR*4)(r31)
        cmpwi   r0,0
        bne     L(do_sigret)
@@ -223,11 +228,25 @@ L(error_exit):
        blr
 
 L(do_sigret):
-       addi    r1,r31,-0xd0
+       addi    r1,r4,-0xd0
        li      r0,SYS_ify(rt_sigreturn)
        sc
        /* NOTREACHED */
 
 PSEUDO_END(__swapcontext)
 
-weak_alias(__swapcontext, swapcontext)
+versioned_symbol (libc, __swapcontext, swapcontext, GLIBC_2_3_3)
+
+#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3_3)
+
+#define _ERRNO_H       1
+#include <bits/errno.h>
+
+ENTRY (__swapcontext_stub)
+       li      r3,ENOSYS
+       b       JUMPTARGET(__syscall_error)
+       END (__swapcontext_stub)
+
+compat_symbol (libc, __swapcontext_stub, swapcontext, GLIBC_2_1)
+
+#endif
index e88a025d6a75f55d04ca722442cb9e196e443af1..1ae082a3ef9cbd5b63b036ec7e71050d447bb364 100644 (file)
 #define _UC_LINK       4
 #define _UC_STACK_SP   8
 #define _UC_STACK_SIZE 16
-#define _UC_SIGMASK    64
-#define _UC_GREGS      192
-#define _UC_FREGS      384
-#define _UC_VREGS      656
+#define _UC_REGS_PTR   48
+#define _UC_SIGMASK    52
+#define _UC_REG_SPACE  180
+
+/* offsets within mcontext_t */
+#define _UC_GREGS      0
+#define _UC_FREGS      192
+#define _UC_VREGS      464
index 9ce93c8197c7e1c664dd269ee86e1dafae4fbfdf..4bb8bb26d03fce5bf3c3e152708fdf7fe5be398f 100644 (file)
@@ -74,14 +74,40 @@ typedef struct ucontext
     struct ucontext *uc_link;
     stack_t uc_stack;
 #if __WORDSIZE == 32
-    /* These fields are for backwards compatibility. */
+    /*
+     * These fields are set up this way to maximize source and
+     * binary compatibility with code written for the old
+     * ucontext_t definition, which didn't include space for the
+     * registers.
+     *
+     * Different versions of the kernel have stored the registers on
+     * signal delivery at different offsets from the ucontext struct.
+     * Programs should thus use the uc_mcontext.uc_regs pointer to
+     * find where the registers are actually stored.  The registers
+     * will be stored within the ucontext_t struct but not necessarily
+     * at a fixed address.  As a side-effect, this lets us achieve
+     * 16-byte alignment for the register storage space if the
+     * Altivec registers are to be saved, without requiring 16-byte
+     * alignment on the whole ucontext_t.
+     *
+     * The uc_mcontext.regs field is included for source compatibility
+     * with programs written against the older ucontext_t definition,
+     * and its name should therefore not change.  The uc_pad field
+     * is for binary compatibility with programs compiled against the
+     * old ucontext_t; it ensures that uc_mcontext.regs and uc_sigmask
+     * are at the same offset as previously.
+     */
     int uc_pad[7];
-    mcontext_t *uc_regs;
-    unsigned int uc_oldsigmask[2];
-    int uc_pad2;
-#endif
+    union uc_regs_ptr {
+      struct pt_regs *regs;
+      mcontext_t *uc_regs;
+    } uc_mcontext;
+    sigset_t    uc_sigmask;
+    char uc_reg_space[sizeof(mcontext_t) + 12];  /* last for extensibility */
+#else /* 64-bit */
     sigset_t    uc_sigmask;
     mcontext_t  uc_mcontext;  /* last for extensibility */
+#endif
   } ucontext_t;
 
 #endif /* sys/ucontext.h */