From 75a496875be9b610b9416ed2f5c561ad7e84a76b Mon Sep 17 00:00:00 2001 From: dennis Date: Mon, 12 Jan 2015 02:48:20 +0000 Subject: [PATCH] Replace the branch to __cerror() in powerpc64 syscall stubs with inline code which does what __cerror() was doing. #ifdef that code (i.e. all code) out of cerror.S; __cerror() is no more. This seems to be necessary to fix the link of rescue/rescue, and should have the pleasant side effect of making all other workarounds done to keep the 'b __cerror' working unnecessary. --- lib/libc/arch/powerpc64/SYS.h | 42 ++++++++++++++++++++++------ lib/libc/arch/powerpc64/sys/cerror.S | 23 +++++++-------- 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/lib/libc/arch/powerpc64/SYS.h b/lib/libc/arch/powerpc64/SYS.h index 969c9eeb1e5e..39c1ee399dbf 100644 --- a/lib/libc/arch/powerpc64/SYS.h +++ b/lib/libc/arch/powerpc64/SYS.h @@ -1,13 +1,39 @@ -/* $NetBSD: SYS.h,v 1.3 2014/08/23 02:24:22 matt Exp $ */ +/* $NetBSD: SYS.h,v 1.4 2015/01/12 02:48:20 dennis Exp $ */ #include #include -#ifdef _CALL_AIX -#define BRANCH_TO_CERROR() b ._C_LABEL(__cerror); nop -#else -#define BRANCH_TO_CERROR() b _C_LABEL(__cerror) -#endif +/* + * Inline what __cerror() is generally used to do since branching + * to __cerror() can't be done reliably with the powerpc64 ABI. + */ +#ifdef _REENTRANT +#define _DO_CERROR_SF_SZ (SF_SZ + SF_ALIGN(8)) +#define _DO_CERROR() mflr %r0 ;\ + streg %r31,-8(%r1) ;\ + streg %r0,SF_LR(%r1) ;\ + stptru %r1,-_DO_CERROR_SF_SZ(%r1) ;\ + mr %r31,%r3 ;\ + bl PIC_PLT(_C_LABEL(__errno)) ;\ + nop ;\ + stint %r31,0(%r3) ;\ + addi %r1,%r1,_DO_CERROR_SF_SZ ;\ + ldreg %r0,SF_LR(%r1) ;\ + ldreg %r31,-8(%r1) ;\ + mtlr %r0 ;\ + li %r3,-1 ;\ + li %r4,-1 ;\ + blr +#else /* !_REENTRANT */ +#define _DO_CERROR() lwz %r4,_C_LABEL(errno)@got(%r2) ;\ + stw %r3,0(%r4) ;\ + li %r3,-1 ;\ + li %r4,-1 ;\ + blr +#endif /* _REENTRANT */ + +/* Clearly BRANCH_TO_CERROR() no longer does that... */ +#define BRANCH_TO_CERROR() _DO_CERROR() #define _DOSYSCALL(x) li %r0,(SYS_ ## x) ;\ sc @@ -19,7 +45,7 @@ #define _SYSCALL(x,y) .text ;\ .p2align 2 ;\ - 2: BRANCH_TO_CERROR() ;\ + 2: _DO_CERROR() ;\ _SYSCALL_NOERROR(x,y) ;\ bso 2b @@ -33,7 +59,7 @@ #define PSEUDO(x,y) _SYSCALL_NOERROR(x,y) ;\ bnslr ;\ - BRANCH_TO_CERROR() ;\ + _DO_CERROR() ;\ END(x) #define RSYSCALL_NOERROR(x) PSEUDO_NOERROR(x,x) diff --git a/lib/libc/arch/powerpc64/sys/cerror.S b/lib/libc/arch/powerpc64/sys/cerror.S index e7b371bc4875..25940a1543d1 100644 --- a/lib/libc/arch/powerpc64/sys/cerror.S +++ b/lib/libc/arch/powerpc64/sys/cerror.S @@ -1,5 +1,8 @@ -/* $NetBSD: cerror.S,v 1.6 2014/08/23 02:24:22 matt Exp $ */ +/* $NetBSD: cerror.S,v 1.7 2015/01/12 02:48:20 dennis Exp $ */ +/* Now inlined in the syscall stubs. Keep code for a while for mind changes. */ + +#if 0 #include #include "SYS.h" @@ -13,26 +16,24 @@ ENTRY(__cerror) #ifdef _REENTRANT mflr %r0 - streg %r0,__SIZEOF_POINTER__(%r1) - stptru %r1,-(4*__SIZEOF_POINTER__)(%r1) # allocate new stack frame - streg %r31,(3*__SIZEOF_POINTER__)(%r1) + streg %r0,SF_LR(%r1) + streg %r31,-8(%r1) + stptru %r1,-(SF_SZ+16)(%r1) # allocate new stack frame mr %r31,%r3 # stash away in callee-saved register bl PIC_PLT(_C_LABEL(__errno)) nop stint %r31,0(%r3) - ldreg %r31,(3*__SIZEOF_POINTER__)(%r1) - addi %r1,%r1,4*__SIZEOF_POINTER__ - ldreg %r0,__SIZEOF_POINTER__(%r1) + addi %r1,%r1,(SF_SZ+16) + ldreg %r31,-8(%r1) + ldreg %r0,SF_LR(%r1) mtlr %r0 #else - .pushsection ".toc", "aw" -.Lerrno:.tc errno[TC], errno - .popsection - lwz %r4,_C_LABEL(.Lerrno)@toc(%r2) + lwz %r4,_C_LABEL(errno)@got(%r2) stw %r3,0(%r4) #endif /* _REENTRANT */ li %r3,-1 li %r4,-1 blr END(__cerror) +#endif /* 0 */