powerpc64 rescue/rescue link failures
Dennis Ferguson <[email protected]> Sat, 10 Jan 2015 15:59:59 -0800
| Newsgroups | gmane.os.netbsd.ports.powerpc |
|---|---|
| Message-ID | <[email protected]> |
Since the January 2 fix to the powerpc64 loader to properly complain about this the macppc64 build has been failing while linking rescue/rescue, this way: # link rescue/rescue [...] /build/macppc64/obj/tooldir.NetBSD-7.99.3-amd64/lib/gcc/powerpc64--netbsd/4.8.4/../../../../powerpc64--netbsd/bin/ld: /build/macppc64/obj/destdir.macppc/usr/lib/libc.a(writev.o): In function `._sys_writev': (.text+0xc): call to `.__cerror' lacks nop, can't restore toc; (-mcmodel=small toc adjust stub)/build/macppc64/obj/tooldir.NetBSD-7.99.3-amd64/lib/gcc/powerpc64--netbsd/4.8.4/../../../../powerpc64--netbsd/bin/ld: final link failed: Bad value The problem is with the tail call to __cerror() which each system call stub does (despite what the error message says). I can fix this by brute force with the attached patch, which inlines __cerror() everywhere it is used, but I was wondering if there was a better way. I see .hidden sometimes being used for this but I have no idea if, or how, that might help this case. Dennis Ferguson
SYS.h.patch
(application/octet-stream, 1.7 KB)
Index: lib/libc/arch/powerpc64/SYS.h =================================================================== RCS file: /cvsroot/src/lib/libc/arch/powerpc64/SYS.h,v retrieving revision 1.3 diff -u -r1.3 SYS.h --- lib/libc/arch/powerpc64/SYS.h 23 Aug 2014 02:24:22 -0000 1.3 +++ lib/libc/arch/powerpc64/SYS.h 10 Jan 2015 23:16:08 -0000 @@ -3,11 +3,34 @@ #include <machine/asm.h> #include <sys/syscall.h> -#ifdef _CALL_AIX -#define BRANCH_TO_CERROR() b ._C_LABEL(__cerror); nop -#else -#define BRANCH_TO_CERROR() b _C_LABEL(__cerror) -#endif +#ifdef _REENTRANT +#define DO_CERROR() mflr %r0 ;\ + streg %r0,__SIZEOF_POINTER__(%r1) ;\ + stptru %r1,-(4*__SIZEOF_POINTER__)(%r1);\ + streg %r31,(3*__SIZEOF_POINTER__)(%r1);\ + mr %r31,%r3 ;\ + 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) ;\ + mtlr %r0 ;\ + li %r3,-1 ;\ + li %r4,-1 ;\ + blr +#else /* !_REENTRANT */ +#define DO_CERROR() .pushsection ".toc", "aw" ;\ + .Lerrno:.tc errno[TC], errno ;\ + .popsection ;\ + lwz %r4,_C_LABEL(.Lerrno)@toc(%r2) ;\ + stw %r3,0(%r4) ;\ + li %r3,-1 ;\ + li %r4,-1 ;\ + blr +#endif /* _REENTRANT */ + +#define BRANCH_TO_CERROR() DO_CERROR() #define _DOSYSCALL(x) li %r0,(SYS_ ## x) ;\ sc @@ -19,7 +42,7 @@ #define _SYSCALL(x,y) .text ;\ .p2align 2 ;\ - 2: BRANCH_TO_CERROR() ;\ + 2: DO_CERROR() ;\ _SYSCALL_NOERROR(x,y) ;\ bso 2b @@ -33,7 +56,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)