PowerPC64 ABI fixes

This commit is contained in:
Alan Modra 2010-08-12 09:19:19 -07:00 committed by Ulrich Drepper
parent 026373745e
commit bebff237c5
16 changed files with 315 additions and 235 deletions

View file

@ -1,3 +1,40 @@
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-08-12 Andreas Schwab <schwab@redhat.com>
[BZ #11904]

View file

@ -1,3 +1,14 @@
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-07-06 Andreas Schwab <schwab@redhat.com>
* sysdeps/unix/sysv/linux/pthread_getname.c (pthread_getname_np):

View file

@ -52,51 +52,70 @@
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

View 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)

View 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 */

View 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 */

View file

@ -27,42 +27,50 @@
parm1 (r3) and the index (r0) need to be converted to an offset
(index * 24) in parm2 (r4). */
EALIGN(_dl_runtime_resolve, 4, 0)
#define FRAME_SIZE 176
/* 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; Use local var space rather than the parameter save area,
because gcc as of 2010/05 doesn't allocate a proper stack frame for
a function that makes no calls except for __tls_get_addr and we
might be here resolving the __tls_get_addr call. */
#define INT_PARMS 112
EALIGN(_dl_runtime_resolve, 4, 0)
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 +78,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 +186,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 +215,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 +275,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 +318,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 +382,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 +430,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)

View 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

View file

@ -39,10 +39,33 @@
#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))

View file

@ -27,19 +27,32 @@
#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 */

View file

@ -27,14 +27,28 @@
.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
@ -46,11 +60,20 @@
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

View 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))

View 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)
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
L(badargs):
li r3,EINVAL
b JUMPTARGET(__syscall_error)
cfi_startproc
END (BP_SYM (__clone))
weak_alias (BP_SYM (__clone), BP_SYM (clone))

View 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

View 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)
@ -49,11 +47,14 @@
# 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)

View 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