]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix PowerPC64 glibc assembly to properly work with the linker automatic
authorAlan Modra <amodra@gmail.com>
Wed, 12 May 2010 04:43:15 +0000 (23:43 -0500)
committerRyan Arnold <ryanarn@etna.rchland.ibm.com>
Wed, 12 May 2010 04:43:41 +0000 (23:43 -0500)
multiple toc support, which may be needed when a static libc is linked into a
large app.  The requirements are: a) No tail calls are allowed to functions in
a different object file, ie. a plain branch is not allowed.  b) All calls to
functions in a different object file must be followed by a nop.

On PowerPC64, the parameter save area and the cr save location for the current
function are in the previous frame, just like the lr save location.  The
parameter save area, cr save location and lr save location in the current
frame are for use by *called* functions.  In a number of places, glibc
assembly used the wrong area, leaving those functions at the mercy of any
called functions.  We just happen to be lucky so far, but that may change with
future versions of gcc.

16 files changed:
ChangeLog
nptl/ChangeLog
nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
sysdeps/powerpc/powerpc32/power4/memcmp.S
sysdeps/powerpc/powerpc64/bsd-_setjmp.S
sysdeps/powerpc/powerpc64/bsd-setjmp.S
sysdeps/powerpc/powerpc64/dl-trampoline.S
sysdeps/powerpc/powerpc64/fpu/s_copysign.S
sysdeps/powerpc/powerpc64/setjmp-common.S
sysdeps/powerpc/powerpc64/setjmp.S
sysdeps/powerpc/powerpc64/sysdep.h
sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S
sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S
sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S
sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S

index e7f607fc2abcaecea07b869f858dd45a6e49d324..a16a1fba85374a4f77da9bcd471ecd63d897de7c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,39 @@
+2010-05-01  Alan Modra  <amodra@gmail.com>
+       * sysdeps/powerpc/powerpc32/power4/memcmp.S: Correct cfi for r24.
+       * sysdeps/powerpc/powerpc64/bsd-_setjmp.S: Move contents..
+       * sysdeps/powerpc/powerpc64/bsd-setjmp.S: ..and these too..
+       * sysdeps/powerpc/powerpc64/setjmp.S: ..to here..
+       * sysdeps/powerpc/powerpc64/setjmp-common.S: ..and here, with some
+       tidying.  Don't tail-call __sigjmp_save for static lib.
+       * sysdeps/powerpc/powerpc64/sysdep.h (SAVE_ARG, REST_ARG): Correct
+       save location.
+       (CFI_SAVE_ARG, CFI_REST_ARG): New macros.
+       (CALL_MCOUNT): Add eh info, and nop after bl.
+       (TAIL_CALL_SYSCALL_ERROR): New macro.
+       (PSEUDO_RET): Use it.
+       * sysdeps/powerpc/powerpc64/dl-trampoline.S (_dl_runtime_resolve):
+       Correct save location of integer regs and cr.
+       (_dl_profile_resolve): Correct cr save location.  Delete nops
+       after bl when SHARED.  Reduce cfi size a little by better
+       placement of cfi directives.
+       * sysdeps/powerpc/powerpc64/fpu/s_copysign.S (__copysign): Don't
+       make a stack frame.  Instead use parm save area as a temp.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S (__brk): Don't
+       make a stack frame.  Use TAIL_CALL_SYSCALL_ERROR.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S (__clone):
+       Don't make a stack frame for parent, use parm save area.
+       Increase child stack frame to 112 bytes.  Don't save unused reg,
+       and adjust reg usage.  Set up cfi on error recovery and
+       epilogue of parent, and use TAIL_CALL_SYSCALL_ERROR, PSEUDO_RET.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S
+       (__makecontext): Add dummy nop after jump to exit.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S (__socket):
+       Use correct parm save area and cr save, reduce stack frame.
+       Correct cfi for possible PSEUDO_RET frame setup.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S (__vfork):
+       Branch to local label emitted by PSEUDO_RET rather than
+       __syscall_error.
+
 2010-03-10  Luis Machado  <luisgpm@br.ibm.com>
        * sysdeps/powerpc/powerpc64/power7/memcpy.S: New file.
        * sysdeps/powerpc/powerpc32/power7/memcpy.S: New file.
index dde74f45eeac0784e5437730229c468bb785f7c7..d9f9ef635d3bf339fb8d8933dd26d327dd29f0fc 100644 (file)
@@ -1,3 +1,13 @@
+2010-05-01  Alan Modra  <amodra@gmail.com>
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
+       (PSEUDO): Use correct cr save.  Don't use wrong parm save area
+       to save temps.  Correct cfi for possible later frame manipulation.
+       (DOCARGS_1, UNDOCARGS_1): Use the correct parm save area.
+       (DOCARGS_2, UNDOCARGS_2, DOCARGS_3, UNDOCARGS_3): Likewise.
+       (DOCARGS_4, UNDOCARGS_4, DOCARGS_5, UNDOCARGS_5): Likewise.
+       (DOCARGS_6, UNDOCARGS_6): Likewise.
+       (CENABLE, CDISABLE): Add nops for non-shared calls.
+
 2010-03-23  Luis Machado  <luisgpm@br.ibm.com>
 
        * pthread_cond_timedwait.c: Add check for
index 707765ab58e7278c4da9b45665a88379c658c525..597630cea48faf9d8def533ee1d78a662c35e693 100644 (file)
     cfi_offset (lr, 16);                                               \
     DOCARGS_##args;    /* save syscall args around CENABLE.  */        \
     CENABLE;                                                           \
-    std  3,72(1);      /* store CENABLE return value (MASK).  */       \
+    std  3,112(1);     /* store CENABLE return value (MASK).  */       \
     UNDOCARGS_##args;  /* restore syscall args.  */                    \
     DO_CALL (SYS_ify (syscall_name));                                  \
     mfcr 0;            /* save CR/R3 around CDISABLE.  */              \
-    std  3,64(1);                                                      \
-    std  0,8(1);                                                       \
-    ld   3,72(1);      /* pass MASK to CDISABLE.  */                   \
+    std  3,120(1);                                                     \
+    std  0,128+8(1);                                                   \
+    cfi_offset (cr, 8);                                                        \
+    ld   3,112(1);     /* pass MASK to CDISABLE.  */                   \
     CDISABLE;                                                          \
     ld   9,128+16(1);                                                  \
-    ld   0,8(1);       /* restore CR/R3. */                            \
-    ld   3,64(1);                                                      \
+    ld   0,128+8(1);   /* restore CR/R3. */                            \
+    ld   3,120(1);                                                     \
     mtlr 9;                                                            \
     mtcr 0;                                                            \
-    addi 1,1,128;
+    addi 1,1,128;                                                      \
+    cfi_adjust_cfa_offset (-128);                                      \
+    cfi_restore (lr);                                                  \
+    cfi_restore (cr)
 
 # define DOCARGS_0
 # define UNDOCARGS_0
 
-# define DOCARGS_1     std 3,80(1); DOCARGS_0
-# define UNDOCARGS_1   ld 3,80(1); UNDOCARGS_0
+# define DOCARGS_1     std 3,128+48(1); DOCARGS_0
+# define UNDOCARGS_1   ld 3,128+48(1); UNDOCARGS_0
 
-# define DOCARGS_2     std 4,88(1); DOCARGS_1
-# define UNDOCARGS_2   ld 4,88(1); UNDOCARGS_1
+# define DOCARGS_2     std 4,128+56(1); DOCARGS_1
+# define UNDOCARGS_2   ld 4,128+56(1); UNDOCARGS_1
 
-# define DOCARGS_3     std 5,96(1); DOCARGS_2
-# define UNDOCARGS_3   ld 5,96(1); UNDOCARGS_2
+# define DOCARGS_3     std 5,128+64(1); DOCARGS_2
+# define UNDOCARGS_3   ld 5,128+64(1); UNDOCARGS_2
 
-# define DOCARGS_4     std 6,104(1); DOCARGS_3
-# define UNDOCARGS_4   ld 6,104(1); UNDOCARGS_3
+# define DOCARGS_4     std 6,128+72(1); DOCARGS_3
+# define UNDOCARGS_4   ld 6,128+72(1); UNDOCARGS_3
 
-# define DOCARGS_5     std 7,112(1); DOCARGS_4
-# define UNDOCARGS_5   ld 7,112(1); UNDOCARGS_4
+# define DOCARGS_5     std 7,128+80(1); DOCARGS_4
+# define UNDOCARGS_5   ld 7,128+80(1); UNDOCARGS_4
 
-# define DOCARGS_6     std 8,120(1); DOCARGS_5
-# define UNDOCARGS_6   ld 8,120(1); UNDOCARGS_5
+# define DOCARGS_6     std 8,128+88(1); DOCARGS_5
+# define UNDOCARGS_6   ld 8,128+88(1); UNDOCARGS_5
 
 # ifdef IS_IN_libpthread
-#  define CENABLE      bl JUMPTARGET(__pthread_enable_asynccancel)
-#  define CDISABLE     bl JUMPTARGET(__pthread_disable_asynccancel)
+#  ifdef SHARED
+#   define CENABLE     bl JUMPTARGET(__pthread_enable_asynccancel)
+#   define CDISABLE    bl JUMPTARGET(__pthread_disable_asynccancel)
+#  else
+#   define CENABLE     bl JUMPTARGET(__pthread_enable_asynccancel); nop
+#   define CDISABLE    bl JUMPTARGET(__pthread_disable_asynccancel); nop
+#  endif
 # elif !defined NOT_IN_libc
-#  define CENABLE      bl JUMPTARGET(__libc_enable_asynccancel)
-#  define CDISABLE     bl JUMPTARGET(__libc_disable_asynccancel)
+#  ifdef SHARED
+#   define CENABLE     bl JUMPTARGET(__libc_enable_asynccancel)
+#   define CDISABLE    bl JUMPTARGET(__libc_disable_asynccancel)
+#  else
+#   define CENABLE     bl JUMPTARGET(__libc_enable_asynccancel); nop
+#   define CDISABLE    bl JUMPTARGET(__libc_disable_asynccancel); nop
+#  endif
 # elif defined IS_IN_librt
-#  define CENABLE      bl JUMPTARGET(__librt_enable_asynccancel)
-#  define CDISABLE     bl JUMPTARGET(__librt_disable_asynccancel)
+#  ifdef SHARED
+#   define CENABLE     bl JUMPTARGET(__librt_enable_asynccancel)
+#   define CDISABLE    bl JUMPTARGET(__librt_disable_asynccancel)
+#  else
+#   define CENABLE     bl JUMPTARGET(__librt_enable_asynccancel); nop
+#   define CDISABLE    bl JUMPTARGET(__librt_disable_asynccancel); nop
+#  endif
 # else
 #  error Unsupported library
 # endif
index 75b328403aa5015739d9265bd49821a634fa2615..fe67833dff5f92ceb3d5b45206952f8c9f34ec81 100644 (file)
@@ -646,7 +646,7 @@ L(Wunaligned):
        cfi_offset(r25,(24-64))
        andi.   rBITDIF, rN, 12  /* Get the W remainder */
         stw     r24,20(r1)     
-       cfi_offset(r24,(24-64))
+       cfi_offset(r24,(20-64))
        slwi    rSHL, rSHL, 3
        lwz     rWORD6, 0(rSTR2)
        lwzu    rWORD8, 4(rSTR2)
index 82b79a80986fa449c59ab669e9a4b69a2777cca8..86d49b1c6e3bc00658ca67b5d7c97d1dac24b9fb 100644 (file)
@@ -1,66 +1 @@
-/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'.  PowerPC32/64 version.
-   Copyright (C) 1994, 1997, 1999, 2000, 2002, 2003, 2004
-   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.  */
-#include <shlib-compat.h>
-#include <libc-symbols.h>
-#include <sysdep.h>
-#include <bp-sym.h>
-
-#if defined NOT_IN_libc
-/* Build a non-versioned object for rtld-*.  */
-ENTRY (BP_SYM (_setjmp))
-       CALL_MCOUNT 1
-       li r4,0                 /* Set second argument to 0.  */
-       b JUMPTARGET (__sigsetjmp_ent)
-END (BP_SYM (_setjmp))
-libc_hidden_def (_setjmp)
-
-#else
-/* Build a versioned object for libc.  */
-# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
-symbol_version (__novmx_setjmp,_setjmp,GLIBC_2.3);
-
-ENTRY (BP_SYM (__novmx_setjmp))
-       CALL_MCOUNT 1
-       li r4,0                 /* Set second argument to 0.  */
-       b JUMPTARGET (__novmx__sigsetjmp_ent)
-END (BP_SYM (__novmx_setjmp))
-libc_hidden_def (__novmx_setjmp)
-# endif /* defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4) */
-
-default_symbol_version (__vmx_setjmp,_setjmp,GLIBC_2.3.4)
-/* __GI__setjmp prototype is needed for ntpl i.e. _setjmp is defined
-   as a libc_hidden_proto & is used in sysdeps/generic/libc-start.c
-   if HAVE_CLEANUP_JMP_BUF is defined */
-ENTRY (BP_SYM (__GI__setjmp))
-#if defined SHARED && !defined IS_IN_rtld
-       std r2,40(r1)   /* Save the callers TOC in the save area.  */
-#endif
-       CALL_MCOUNT 1
-       li r4,0                 /* Set second argument to 0.  */
-       b JUMPTARGET (__vmx__sigsetjmp_ent)
-END (BP_SYM (__GI__setjmp))
-
-ENTRY (BP_SYM (__vmx_setjmp))
-       CALL_MCOUNT 1
-       li r4,0                 /* Set second argument to 0.  */
-       b JUMPTARGET (__vmx__sigsetjmp_ent)
-END (BP_SYM (__vmx_setjmp))
-libc_hidden_def (__vmx_setjmp)
-#endif /* !NOT_IN_libc */
+/* _setjmp moved to setjmp-common.S */
index 543e83faa3185f671697ed3cc7df936cb2bf6f1d..38b734fcb4c75ce1a784e2ec06b780e8bbc92d51 100644 (file)
@@ -1,45 +1 @@
-/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'.  PowerPC32/64 version.
-   Copyright (C) 1994,1997,1999,2000,2003,2004 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.  */
-#include <shlib-compat.h>
-#include <libc-symbols.h>
-#include <sysdep.h>
-#include <bp-sym.h>
-
-#if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
-
-
-ENTRY (__novmxsetjmp)
-       CALL_MCOUNT 1
-       li r4,1                 /* Set second argument to 1.  */
-       b JUMPTARGET (__novmx__sigsetjmp_ent)
-END (__novmxsetjmp)
-strong_alias (__novmxsetjmp, __novmx__setjmp)
-symbol_version (__novmxsetjmp, setjmp, GLIBC_2.3)
-
-#endif  /*  defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4) */
-
-
-ENTRY (__vmxsetjmp)
-       CALL_MCOUNT 1
-       li r4,1                 /* Set second argument to 1.  */
-       b JUMPTARGET (__vmx__sigsetjmp_ent)
-END (__vmxsetjmp)
-strong_alias (__vmxsetjmp, __vmx__setjmp)
-strong_alias (__vmx__sigsetjmp, __setjmp)
-default_symbol_version (__vmxsetjmp, setjmp, GLIBC_2.3.4)
+/* setjmp moved to setjmp-common.S */
index 9ca394dda2e3f3ee42ecebaef47a012948d70786..40029aff859dd5c3f2b473fb3b5599414f4feea2 100644 (file)
    parm1 (r3) and the index (r0) need to be converted to an offset
    (index * 24) in parm2 (r4).  */
 
+#define FRAME_SIZE 112
+#define INT_PARMS FRAME_SIZE+48
 EALIGN(_dl_runtime_resolve, 4, 0)
 /* We need to save the registers used to pass parameters, ie. r3 thru
-   r10; the registers are saved in a stack frame.  */
-       stdu    r1,-128(r1)
-       cfi_adjust_cfa_offset (128)
-       std     r3,48(r1)
+   r10; the registers are saved in the parameter save area.  */
+       stdu    r1,-FRAME_SIZE(r1)
+       cfi_adjust_cfa_offset (FRAME_SIZE)
+       std     r3,INT_PARMS+0(r1)
        mr      r3,r11
-       std     r4,56(r1)
+       std     r4,INT_PARMS+8(r1)
        sldi    r4,r0,1
-       std     r5,64(r1)
+       std     r5,INT_PARMS+16(r1)
        add     r4,r4,r0
-       std     r6,72(r1)
+       std     r6,INT_PARMS+24(r1)
        sldi    r4,r4,3
-       std     r7,80(r1)
+       std     r7,INT_PARMS+32(r1)
        mflr    r0
-       std     r8,88(r1)
-/* Store the LR in the LR Save area of the previous frame.  */
-       std     r0,128+16(r1)
+       std     r8,INT_PARMS+40(r1)
+/* Store the LR in the LR Save area.  */
+       std     r0,FRAME_SIZE+16(r1)
        cfi_offset (lr, 16)
        mfcr    r0
-       std     r9,96(r1)
-       std     r10,104(r1)
+       std     r9,INT_PARMS+48(r1)
+       std     r10,INT_PARMS+56(r1)
 /* I'm almost certain we don't have to save cr...  be safe.  */
-       std     r0,8(r1)
+       std     r0,FRAME_SIZE+8(r1)
        bl      JUMPTARGET(_dl_fixup)
+#ifndef SHARED
+       nop
+#endif
 /* Put the registers back.  */
-       ld      r0,128+16(r1)
-       ld      r10,104(r1)
-       ld      r9,96(r1)
-       ld      r8,88(r1)
-       ld      r7,80(r1)
+       ld      r0,FRAME_SIZE+16(r1)
+       ld      r10,INT_PARMS+56(r1)
+       ld      r9,INT_PARMS+48(r1)
+       ld      r8,INT_PARMS+40(r1)
+       ld      r7,INT_PARMS+32(r1)
        mtlr    r0
-       ld      r0,8(r1)
-       ld      r6,72(r1)
-       ld      r5,64(r1)
-       ld      r4,56(r1)
+       ld      r0,FRAME_SIZE+8(r1)
+       ld      r6,INT_PARMS+24(r1)
+       ld      r5,INT_PARMS+16(r1)
+       ld      r4,INT_PARMS+8(r1)
        mtcrf   0xFF,r0
 /* Load the target address, toc and static chain reg from the function
    descriptor returned by fixup.  */
@@ -70,11 +75,13 @@ EALIGN(_dl_runtime_resolve, 4, 0)
        ld      r2,8(r3)
        mtctr   r0
        ld      r11,16(r3)
-       ld      r3,48(r1)
+       ld      r3,INT_PARMS+0(r1)
 /* Unwind the stack frame, and jump.  */
-       addi    r1,r1,128
+       addi    r1,r1,FRAME_SIZE
        bctr
 END(_dl_runtime_resolve)
+#undef FRAME_SIZE
+#undef INT_PARMS
 
        /* Stack layout:
          +592   previous backchain
@@ -176,13 +183,13 @@ EALIGN(_dl_profile_resolve, 4, 0)
 /* Spill r30, r31 to preserve the link_map* and reloc_addr, in case we
    need to call _dl_call_pltexit.  */
        std     r31,-8(r1)
-       cfi_offset(r31,-8)
        std     r30,-16(r1)
-       cfi_offset(r30,-16)
 /* We need to save the registers used to pass parameters, ie. r3 thru
    r10; the registers are saved in a stack frame.  */
        stdu    r1,-FRAME_SIZE(r1)
        cfi_adjust_cfa_offset (FRAME_SIZE)
+       cfi_offset(r31,-8)
+       cfi_offset(r30,-16)
        std     r3,INT_PARMS+0(r1)
        mr      r3,r11
        std     r4,INT_PARMS+8(r1)
@@ -205,7 +212,7 @@ EALIGN(_dl_profile_resolve, 4, 0)
        std     r10,INT_PARMS+56(r1)
        std     r8,CALLING_SP(r1)
 /* I'm almost certain we don't have to save cr...  be safe.  */
-       std     r0,8(r1)
+       std     r0,FRAME_SIZE+8(r1)
        ld      r12,.LC__dl_hwcap@toc(r2)
 #ifdef SHARED
        /* Load _rtld-global._dl_hwcap.  */
@@ -265,7 +272,9 @@ L(saveFP):
        mr      r30,r4
        std     r0,0(r7)
        bl      JUMPTARGET(_dl_profile_fixup)
+#ifndef SHARED
        nop
+#endif
 /* Test *framesizep > 0 to see if need to do pltexit processing.  */
        ld      r0,STACK_FRAME(r1)
 /* Put the registers back.  */
@@ -306,7 +315,7 @@ L(restoreFXR):
        ld      r8,INT_PARMS+40(r1)
        ld      r7,INT_PARMS+32(r1)
        mtlr    r0
-       ld      r0,8(r1)
+       ld      r0,FRAME_SIZE+8(r1)
        ld      r6,INT_PARMS+24(r1)
        ld      r5,INT_PARMS+16(r1)
        ld      r4,INT_PARMS+8(r1)
@@ -370,7 +379,7 @@ L(restoreFXR2):
        ld      r8,INT_PARMS+40(r1)
        ld      r7,INT_PARMS+32(r1)
        mtlr    r0
-       ld      r0,8(r1)
+       ld      r0,FRAME_SIZE+8(r1)
        ld      r6,INT_PARMS+24(r1)
        ld      r5,INT_PARMS+16(r1)
        ld      r4,INT_PARMS+8(r1)
@@ -418,7 +427,9 @@ L(callpltexit):
        addi    r5,r1,INT_PARMS
        addi    r6,r1,INT_RTN
        bl      JUMPTARGET(_dl_call_pltexit)
+#ifndef SHARED
        nop
+#endif
 /* Restore the return values from target function.  */
        lwz     r12,VR_VRSAVE(r1)
        ld      r3,INT_RTN(r1)
index 38171e31d717fed6bfff4a72ac2cecec519f05b6..ff7490629e9e73da896ec3a58ad5ecb4fe751ba0 100644 (file)
@@ -28,15 +28,12 @@ ENTRY(__copysign)
 /* double [f1] copysign (double [f1] x, double [f2] y);
    copysign(x,y) returns a value with the magnitude of x and
    with the sign bit of y.  */
-       stdu    r1,-48(r1)
-       cfi_adjust_cfa_offset (48)
-       stfd    fp2,24(r1)
+       stfd    fp2,56(r1)
        nop
        nop
        nop
-       ld      r3,24(r1)
+       ld      r3,56(r1)
        cmpdi   r3,0
-       addi    r1,r1,48
        blt     L(0)
        fabs    fp1,fp1
        blr
index 606eef5935769f3971faefc70b4420e308dfb21c..a059a91f8bb656ad68f1dc5591d79077ac566017 100644 (file)
 #endif
 
        .machine        "altivec"
+ENTRY (setjmp)
+       CALL_MCOUNT 1
+       li r4,1                 /* Set second argument to 1.  */
+       b JUMPTARGET (GLUE(__sigsetjmp,_ent))
+END (setjmp)
+
+#if defined SHARED && !defined IS_IN_rtld && !defined __NO_VMX__
+/* When called from within libc we need a special version of _setjmp
+   that saves r2 since the call won't go via a plt call stub.  See
+   bugz #269.  __GI__setjmp is used in csu/libc-start.c when
+   HAVE_CLEANUP_JMP_BUF is defined.  */
+ENTRY (BP_SYM (__GI__setjmp))
+       std r2,40(r1)           /* Save the callers TOC in the save area.  */
+       cfi_endproc
+END_2 (BP_SYM (__GI__setjmp))
+/* Fall thru. */
+#endif
+
+ENTRY (BP_SYM (_setjmp))
+       CALL_MCOUNT 1
+       li r4,0                 /* Set second argument to 0.  */
+       b JUMPTARGET (GLUE(__sigsetjmp,_ent))
+END (BP_SYM (_setjmp))
+libc_hidden_def (_setjmp)
+
 ENTRY (BP_SYM (__sigsetjmp))
        CALL_MCOUNT 2
-       .globl JUMPTARGET(GLUE(__sigsetjmp,_ent))
-       .hidden JUMPTARGET(GLUE(__sigsetjmp,_ent))
 JUMPTARGET(GLUE(__sigsetjmp,_ent)):
        CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE)
 #ifdef PTR_MANGLE
@@ -190,7 +213,19 @@ L(no_vmx):
 #if defined NOT_IN_libc && defined IS_IN_rtld
        li      r3,0
        blr
+#elif defined SHARED
+       b       JUMPTARGET (BP_SYM (__sigjmp_save))
 #else
-       b JUMPTARGET (BP_SYM (__sigjmp_save))
+       mflr    r0
+       std     r0,16(r1)
+       stdu    r1,-112(r1)
+       cfi_adjust_cfa_offset(112)
+       cfi_offset(lr,16)
+       bl      JUMPTARGET (BP_SYM (__sigjmp_save))
+       nop
+       ld      r0,112+16(r1)
+       addi    r1,r1,112
+       mtlr    r0
+       blr
 #endif
 END (BP_SYM (__sigsetjmp))
index acbf3728e55e60602c102fd97718160e8b48d0be..83b237ba2aa920b29e11ad4c8fce488788280a7a 100644 (file)
 
 #else /* !NOT_IN_libc */
 /* Build a versioned object for libc.  */
+default_symbol_version (__vmxsetjmp, setjmp, GLIBC_2.3.4)
+default_symbol_version (__vmx_setjmp,_setjmp,GLIBC_2.3.4)
 default_symbol_version (__vmx__sigsetjmp,__sigsetjmp,GLIBC_2.3.4)
+# define setjmp __vmxsetjmp
+# define _setjmp __vmx_setjmp
 # define __sigsetjmp __vmx__sigsetjmp
 # define __sigjmp_save __vmx__sigjmp_save
 # include "setjmp-common.S"
+strong_alias (__vmxsetjmp, __vmx__setjmp)
+strong_alias (__vmx__sigsetjmp, __setjmp)
 
 # if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
+#  undef setjmp
+#  undef _setjmp
 #  undef __sigsetjmp
 #  undef __sigjmp_save
 #  undef JB_SIZE
 #  define __NO_VMX__
+symbol_version (__novmxsetjmp, setjmp, GLIBC_2.3)
+symbol_version (__novmx_setjmp,_setjmp,GLIBC_2.3);
 symbol_version (__novmx__sigsetjmp,__sigsetjmp,GLIBC_2.3)
+#  define setjmp __novmxsetjmp
+#  define _setjmp __novmx_setjmp
 #  define __sigsetjmp __novmx__sigsetjmp
 #  define __sigjmp_save __novmx__sigjmp_save
 #  include "setjmp-common.S"
+strong_alias (__novmxsetjmp, __novmx__setjmp)
 # endif
 #endif /* !NOT_IN_libc */
index 2745d7eb716811308e156f8aec825479efad4fd1..5fc6e4f2f335ba7362f425b5effe06fab1c2f096 100644 (file)
        .macro SAVE_ARG NARG
        .if \NARG
        SAVE_ARG \NARG-1
-       std     2+\NARG,-72+8*(\NARG)(1)
+       std     2+\NARG,40+8*(\NARG)(1)
        .endif
        .endm
 
        .macro REST_ARG NARG
        .if \NARG
        REST_ARG \NARG-1
-       ld      2+\NARG,40+8*(\NARG)(1)
+       ld      2+\NARG,112+40+8*(\NARG)(1)
+       .endif
+       .endm
+
+       .macro CFI_SAVE_ARG NARG
+       .if \NARG
+       CFI_SAVE_ARG \NARG-1
+       cfi_offset(2+\NARG,40+8*(\NARG))
+       .endif
+       .endm
+
+       .macro CFI_REST_ARG NARG
+       .if \NARG
+       CFI_REST_ARG \NARG-1
+       cfi_restore(2+\NARG)
        .endif
        .endm
 
        SAVE_ARG \NARG
        std     r0,16(r1)
        stdu    r1,-112(r1)
+       cfi_adjust_cfa_offset(112)
+       cfi_offset(lr,16)
+       CFI_SAVE_ARG \NARG
        bl      JUMPTARGET (_mcount)
+#ifndef SHARED
+       nop
+#endif
        ld      r0,128(r1)
        REST_ARG \NARG
-       addi    r1,r1,112
        mtlr    r0
+       addi    r1,r1,112
+       cfi_adjust_cfa_offset(-112)
+       cfi_restore(lr)
+       CFI_REST_ARG \NARG
 #endif
        .endm
 
@@ -198,9 +221,37 @@ LT_LABELSUFFIX(name,_name_end): ; \
   ENTRY (name) \
   DO_CALL (SYS_ify (syscall_name));
 
+#ifdef SHARED
+#define TAIL_CALL_SYSCALL_ERROR \
+    b JUMPTARGET(__syscall_error)
+#else
+/* Static version might be linked into a large app with a toc exceeding
+   64k.  We can't put a toc adjusting stub on a plain branch, so can't
+   tail call __syscall_error.  */
+#define TAIL_CALL_SYSCALL_ERROR \
+    .ifdef .Local_syscall_error; \
+    b .Local_syscall_error; \
+    .else; \
+.Local_syscall_error: \
+    mflr 0; \
+    std 0,16(1); \
+    stdu 1,-112(1); \
+    cfi_adjust_cfa_offset(112); \
+    cfi_offset(lr,16); \
+    bl JUMPTARGET(__syscall_error); \
+    nop; \
+    ld 0,112+16(1); \
+    addi 1,1,112; \
+    cfi_adjust_cfa_offset(-112); \
+    mtlr 0; \
+    cfi_restore(lr); \
+    blr; \
+    .endif
+#endif
+
 #define PSEUDO_RET \
     bnslr+; \
-    b JUMPTARGET(__syscall_error)
+    TAIL_CALL_SYSCALL_ERROR
 
 #define ret PSEUDO_RET
 
index f2ac00d4c7288ca2c468b4685c29f7cb3143ed8d..ef574c14fc6b679a5cad6b01532d8e9a4c01d211 100644 (file)
@@ -32,19 +32,16 @@ ENTRY (BP_SYM (__brk))
        CALL_MCOUNT 1
        DISCARD_BOUNDS (r3)     /* the bounds are meaningless, so toss 'em.  */
 
-       stdu    r1,-64(r1)
-       cfi_adjust_cfa_offset (64)
        std     r3,48(r1)
        DO_CALL(SYS_ify(brk))
-       ld     r6,48(r1)
+       ld      r6,48(r1)
        ld      r5,.LC__curbrk@toc(r2)
        std     r3,0(r5)
        cmpld   r6,r3
-       addi    r1,r1,64
        li      r3,0
        blelr+
        li      r3,ENOMEM
-       b       JUMPTARGET(__syscall_error)
+       TAIL_CALL_SYSCALL_ERROR
 END (BP_SYM (__brk))
 
 weak_alias (BP_SYM (__brk), BP_SYM (brk))
index f1a55e64dbb7f0d08cb86add450b5af186141b64..d14da54fd781c7cbf3d73b315a44606581b9ea19 100644 (file)
@@ -46,35 +46,32 @@ ENTRY (BP_SYM (__clone))
        cror    cr0*4+eq,cr1*4+eq,cr0*4+eq
        beq-    cr0,L(badargs)
 
-       /* Set up stack frame for parent.  */
-       stdu    r1,-80(r1)
-       cfi_adjust_cfa_offset (80)
-       std     r29,56(r1)
-       std     r30,64(r1)
-       std     r31,72(r1)
-       cfi_offset(r29,-56)
-       cfi_offset(r30,-64)
-       cfi_offset(r31,-72)
+       /* Save some regs in parm save area.  */
 #ifdef RESET_PID
-       std     r28,48(r1)
-       cfi_offset(r28,-48)
+       std     r29,48(r1)
 #endif
+       std     r30,56(r1)
+       std     r31,64(r1)
+#ifdef RESET_PID
+       cfi_offset(r29,48)
+#endif
+       cfi_offset(r30,56)
+       cfi_offset(r31,64)
 
        /* Set up stack frame for child.  */
        clrrdi  r4,r4,4
        li      r0,0
-       stdu    r0,-48(r4) /* min stack frame is 48 bytes per ABI */
+       stdu    r0,-112(r4) /* min stack frame is 112 bytes per ABI */
 
        /* Save fn, args, stack across syscall.  */
-       mr      r29,r3                  /* Function in r29.  */
-       mr      r30,r4                  /* Stack pointer in r30.  */
+       mr      r30,r3                  /* Function in r30.  */
 #ifdef RESET_PID
-       mr      r28,r5                  /* Flags in r28.  */
+       mr      r29,r5                  /* Flags in r29.  */
 #endif
        mr      r31,r6                  /* Argument in r31.  */
 
-       /* 'flags' argument is first parameter to clone syscall. (The other
-          argument is the stack pointer, already in r4.)  */
+       /* 'flags' argument is first parameter to clone syscall.
+          Second is the stack pointer, already in r4.  */
        mr      r3,r5
   /* Move the parent_tid, child_tid and tls arguments. */
        mr      r5,r7
@@ -94,9 +91,9 @@ ENTRY (BP_SYM (__clone))
        bne-    cr1,L(parent)           /* The '-' is to minimise the race.  */
 
 #ifdef RESET_PID
-       andis.  r0,r28,CLONE_THREAD>>16
+       andis.  r0,r29,CLONE_THREAD>>16
        bne+    cr0,L(oldpid)
-       andi.   r0,r28,CLONE_VM
+       andi.   r0,r29,CLONE_VM
        li      r3,-1
        bne-    cr0,L(nomoregetpid)
        DO_CALL(SYS_ify(getpid))
@@ -108,8 +105,8 @@ L(oldpid):
 
        std     r2,40(r1)
        /* Call procedure.  */
-       ld      r0,0(r29)
-       ld      r2,8(r29)
+       ld      r0,0(r30)
+       ld      r2,8(r30)
        mtctr   r0
        mr      r3,r31
        bctrl
@@ -119,25 +116,35 @@ L(oldpid):
        b       JUMPTARGET(__GI__exit)
 #else
        b       JUMPTARGET(_exit)
+       /* We won't ever get here but provide a nop so that the linker
+          will insert a toc adjusting stub if necessary.  */
+       nop
 #endif
 
+L(badargs):
+       cfi_startproc
+       li      r3,EINVAL
+       TAIL_CALL_SYSCALL_ERROR
+
 L(parent):
        /* Parent.  Restore registers & return.  */
 #ifdef RESET_PID
-       ld      r28,48(r1)
+       cfi_offset(r29,48)
 #endif
-       ld      r31,72(r1)
-       ld      r30,64(r1)
-       ld      r29,56(r1)
-       addi    r1,r1,80
-       bnslr+
-       b       JUMPTARGET(__syscall_error)
-
-L(badargs):
-       li      r3,EINVAL
-       b       JUMPTARGET(__syscall_error)
+       cfi_offset(r30,56)
+       cfi_offset(r31,64)
+#ifdef RESET_PID
+       ld      r29,48(r1)
+#endif
+       ld      r30,56(r1)
+       ld      r31,64(r1)
+#ifdef RESET_PID
+       cfi_restore(r29)
+#endif
+       cfi_restore(r30)
+       cfi_restore(r31)
+       PSEUDO_RET
 
-       cfi_startproc
 END (BP_SYM (__clone))
 
 weak_alias (BP_SYM (__clone), BP_SYM (clone))
index 4a82802d9660dc907d0fb7f9043b79dd9ec4dbee..18baa39d6a909a1ff9b94d01da0c632eead24e4a 100644 (file)
@@ -154,6 +154,7 @@ L(BADSTATUS):
   b     JUMPTARGET(__GI_exit);
 #else
   b     JUMPTARGET(exit);
+  nop
 #endif
 
   /* The address of the exit code is in the link register.  Store the lr
index 15d8e84c1f0faa8218edeebb7d71f7c35b994ea0..a0ae11594a79c8975f1d7c119255804b26d31d3a 100644 (file)
@@ -39,8 +39,6 @@
 #define NARGS 3
 #endif
 
-#define stackblock 80 /* offset to socket parm area.  */
-
 #ifndef __socket
 # ifndef NO_WEAK_ALIAS
 #  define __socket P(__,socket)
 # endif
 #endif
 
+#define FRAMESIZE 128
+#define stackblock FRAMESIZE+48 /* offset to parm save area.  */
+
        .text
 ENTRY(__socket)
        CALL_MCOUNT NARGS
-       stdu r1,-144(r1)
-       cfi_adjust_cfa_offset(144)
+       stdu r1,-FRAMESIZE(r1)
+       cfi_adjust_cfa_offset(FRAMESIZE)
 #if NARGS >= 1
        std  r3,stackblock(r1)
 #endif
@@ -87,33 +88,39 @@ ENTRY(__socket)
        bne-    .Lsocket_cancel
 #endif
 
-       li    r3,P(SOCKOP_,socket)
+       li      r3,P(SOCKOP_,socket)
        addi    r4,r1,stackblock
        DO_CALL(SYS_ify(socketcall))
-       addi    r1,r1,144
+       addi    r1,r1,FRAMESIZE
+       cfi_adjust_cfa_offset(-FRAMESIZE)
        PSEUDO_RET
 
 #if defined NEED_CANCELLATION && defined CENABLE
 .Lsocket_cancel:
+       cfi_adjust_cfa_offset(FRAMESIZE)
        mflr    r9
-       std   r9,144+16(r1)
+       std     r9,FRAMESIZE+16(r1)
        cfi_offset (lr, 16)
        CENABLE
-       std     r3,72(r1)
-       li        r3,P(SOCKOP_,socket)
+       std     r3,120(r1)
+       li      r3,P(SOCKOP_,socket)
        addi    r4,r1,stackblock
        DO_CALL(SYS_ify(socketcall))
        mfcr    r0
-       std   r3,64(r1)
-       std   r0,8(r1)
-       ld      r3,72(r1)
+       std     r3,112(r1)
+       std     r0,FRAMESIZE+8(r1)
+       cfi_offset (cr, 8)
+       ld      r3,120(r1)
        CDISABLE
-       ld    r4,144+16(r1)
-       ld    r0,8(r1)
-       ld    r3,64(r1)
+       ld      r4,FRAMESIZE+16(r1)
+       ld      r0,FRAMESIZE+8(r1)
+       ld      r3,112(r1)
        mtlr    r4
        mtcr    r0
-       addi    r1,r1,144
+       addi    r1,r1,FRAMESIZE
+       cfi_adjust_cfa_offset(-FRAMESIZE)
+       cfi_restore(lr)
+       cfi_restore(cr)
        PSEUDO_RET
 #endif
 PSEUDO_END (__socket)
index 2f5df38cf8e91dea9b5971c2303b324e7161b97e..14d0c2bf101cb6de9c3c22b849bb324194eee8f9 100644 (file)
@@ -39,7 +39,7 @@ ENTRY (__vfork)
        bnslr+
        /* Check if vfork syscall is known at all.  */
        cmpdi   r3,ENOSYS
-       bne     JUMPTARGET(__syscall_error)
+       bne     .Local_syscall_error
 
 # endif
 #endif