From 2068d5658e99f6cf13dd2648f3542d2c5bcdabfc Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Mon, 17 Apr 2023 14:09:39 -0400 Subject: [PATCH] Revert "Revert "Revert "runtime: consolidate function descriptor definitions on PPC64""" This reverts CL 481075 (a re-apply of previously reverted CL 478917). Reason for revert: CL 481061 causes C TSAN failures and must be reverted. See CL 485275. This CL depends on CL 481061. For #59678. Change-Id: I4bf7f43d9df1ae28e04cd4065552bcbee82ef13f Reviewed-on: https://go-review.googlesource.com/c/go/+/485316 Reviewed-by: Than McIntosh TryBot-Result: Gopher Robot Run-TryBot: Michael Pratt Auto-Submit: Michael Pratt --- src/runtime/asm_ppc64x.h | 20 ++------------------ src/runtime/asm_ppc64x.s | 21 ++++++++++++++++++--- src/runtime/cgo/asm_ppc64x.s | 25 +++++++++++++------------ src/runtime/rt0_aix_ppc64.s | 17 +++++++++++++---- src/runtime/rt0_linux_ppc64.s | 13 ++++++++++--- src/runtime/sys_linux_ppc64x.s | 23 +++++++++++++++++------ 6 files changed, 73 insertions(+), 46 deletions(-) diff --git a/src/runtime/asm_ppc64x.h b/src/runtime/asm_ppc64x.h index 65870fe020f..cce5537a9cb 100644 --- a/src/runtime/asm_ppc64x.h +++ b/src/runtime/asm_ppc64x.h @@ -24,32 +24,16 @@ #define FIXED_FRAME 32 -// aix/ppc64 uses XCOFF which uses function descriptors. -// AIX cannot perform the TOC relocation in a text section. -// Therefore, these descriptors must live in a data section. +// aix/ppc64 uses XCOFF which has function descriptors. #ifdef GOOS_aix #ifdef GOARCH_ppc64 #define GO_PPC64X_HAS_FUNCDESC -#define DEFINE_PPC64X_FUNCDESC(funcname, localfuncname) \ - DATA funcname+0(SB)/8, $localfuncname(SB) \ - DATA funcname+8(SB)/8, $TOC(SB) \ - DATA funcname+16(SB)/8, $0 \ - GLOBL funcname(SB), NOPTR, $24 #endif #endif -// linux/ppc64 uses ELFv1 which uses function descriptors. -// These must also look like ABI0 functions on linux/ppc64 -// to work with abi.FuncPCABI0(sigtramp) in os_linux.go. -// Only static codegen is supported on linux/ppc64, so TOC -// is not needed. +// linux/ppc64 uses ELFv1 which has function descriptors. #ifdef GOOS_linux #ifdef GOARCH_ppc64 #define GO_PPC64X_HAS_FUNCDESC -#define DEFINE_PPC64X_FUNCDESC(funcname, localfuncname) \ - TEXT funcname(SB),NOSPLIT|NOFRAME,$0 \ - DWORD $localfuncname(SB) \ - DWORD $0 \ - DWORD $0 #endif #endif diff --git a/src/runtime/asm_ppc64x.s b/src/runtime/asm_ppc64x.s index 293683f4192..7c866b4bc33 100644 --- a/src/runtime/asm_ppc64x.s +++ b/src/runtime/asm_ppc64x.s @@ -771,11 +771,26 @@ TEXT runtime·setg(SB), NOSPLIT, $0-8 BL runtime·save_g(SB) RET -#ifdef GO_PPC64X_HAS_FUNCDESC -DEFINE_PPC64X_FUNCDESC(setg_gcc<>, _setg_gcc<>) -TEXT _setg_gcc<>(SB),NOSPLIT|NOFRAME,$0-0 +#ifdef GOARCH_ppc64 +#ifdef GOOS_aix +DATA setg_gcc<>+0(SB)/8, $_setg_gcc<>(SB) +DATA setg_gcc<>+8(SB)/8, $TOC(SB) +DATA setg_gcc<>+16(SB)/8, $0 +GLOBL setg_gcc<>(SB), NOPTR, $24 #else TEXT setg_gcc<>(SB),NOSPLIT|NOFRAME,$0-0 + DWORD $_setg_gcc<>(SB) + DWORD $0 + DWORD $0 +#endif +#endif + +// void setg_gcc(G*); set g in C TLS. +// Must obey the gcc calling convention. +#ifdef GOARCH_ppc64le +TEXT setg_gcc<>(SB),NOSPLIT|NOFRAME,$0-0 +#else +TEXT _setg_gcc<>(SB),NOSPLIT|NOFRAME,$0-0 #endif // The standard prologue clobbers R31, which is callee-save in // the C ABI, so we have to use $-8-0 and save LR ourselves. diff --git a/src/runtime/cgo/asm_ppc64x.s b/src/runtime/cgo/asm_ppc64x.s index 7752feb6504..8eb4a421578 100644 --- a/src/runtime/cgo/asm_ppc64x.s +++ b/src/runtime/cgo/asm_ppc64x.s @@ -7,25 +7,26 @@ #include "textflag.h" #include "asm_ppc64x.h" -#ifdef GO_PPC64X_HAS_FUNCDESC -// crosscall2 is marked with go:cgo_export_static. On AIX, this creates and exports -// the symbol name and descriptor as the AIX linker expects, but does not work if -// referenced from within Go. Create and use an aliased descriptor of crosscall2 -// to workaround this. -DEFINE_PPC64X_FUNCDESC(_crosscall2<>, crosscall2) -#define CROSSCALL2_FPTR $_crosscall2<>(SB) -#else -#define CROSSCALL2_FPTR $crosscall2(SB) -#endif - // Set the x_crosscall2_ptr C function pointer variable point to crosscall2. // It's such a pointer chain: _crosscall2_ptr -> x_crosscall2_ptr -> crosscall2 TEXT ·set_crosscall2(SB),NOSPLIT,$0-0 MOVD _crosscall2_ptr(SB), R5 - MOVD CROSSCALL2_FPTR, R6 +#ifdef GOARCH_ppc64 + MOVD $_crosscall2<>(SB), R6 +#else + MOVD $crosscall2(SB), R6 +#endif MOVD R6, (R5) RET +#ifdef GO_PPC64X_HAS_FUNCDESC +// _crosscall2<> is a function descriptor to the real crosscall2. +DATA _crosscall2<>+0(SB)/8, $crosscall2(SB) +DATA _crosscall2<>+8(SB)/8, $TOC(SB) +DATA _crosscall2<>+16(SB)/8, $0 +GLOBL _crosscall2<>(SB), NOPTR, $24 +#endif + // Called by C code generated by cmd/cgo. // func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr) // Saves C callee-saved registers and calls cgocallback with three arguments. diff --git a/src/runtime/rt0_aix_ppc64.s b/src/runtime/rt0_aix_ppc64.s index 1670a809862..86fda568996 100644 --- a/src/runtime/rt0_aix_ppc64.s +++ b/src/runtime/rt0_aix_ppc64.s @@ -3,11 +3,13 @@ // license that can be found in the LICENSE file. #include "textflag.h" -#include "asm_ppc64x.h" // _rt0_ppc64_aix is a function descriptor of the entrypoint function // __start. This name is needed by cmd/link. -DEFINE_PPC64X_FUNCDESC(_rt0_ppc64_aix, __start<>) +DATA _rt0_ppc64_aix+0(SB)/8, $__start<>(SB) +DATA _rt0_ppc64_aix+8(SB)/8, $TOC(SB) +GLOBL _rt0_ppc64_aix(SB), NOPTR, $16 + // The starting function must return in the loader to // initialise some libraries, especially libthread which @@ -35,7 +37,11 @@ TEXT __start<>(SB),NOSPLIT,$-8 BL _main(SB) -DEFINE_PPC64X_FUNCDESC(main, _main) +DATA main+0(SB)/8, $_main(SB) +DATA main+8(SB)/8, $TOC(SB) +DATA main+16(SB)/8, $0 +GLOBL main(SB), NOPTR, $24 + TEXT _main(SB),NOSPLIT,$-8 MOVD $runtime·rt0_go(SB), R12 MOVD R12, CTR @@ -175,7 +181,10 @@ done: MOVD R0, LR RET -DEFINE_PPC64X_FUNCDESC(_rt0_ppc64_aix_lib_go, __rt0_ppc64_aix_lib_go) +DATA _rt0_ppc64_aix_lib_go+0(SB)/8, $__rt0_ppc64_aix_lib_go(SB) +DATA _rt0_ppc64_aix_lib_go+8(SB)/8, $TOC(SB) +DATA _rt0_ppc64_aix_lib_go+16(SB)/8, $0 +GLOBL _rt0_ppc64_aix_lib_go(SB), NOPTR, $24 TEXT __rt0_ppc64_aix_lib_go(SB),NOSPLIT,$0 MOVD _rt0_ppc64_aix_lib_argc<>(SB), R3 diff --git a/src/runtime/rt0_linux_ppc64.s b/src/runtime/rt0_linux_ppc64.s index f527170ed28..c9300a9caf6 100644 --- a/src/runtime/rt0_linux_ppc64.s +++ b/src/runtime/rt0_linux_ppc64.s @@ -3,10 +3,17 @@ // license that can be found in the LICENSE file. #include "textflag.h" -#include "asm_ppc64x.h" -DEFINE_PPC64X_FUNCDESC(_rt0_ppc64_linux, _main<>) -DEFINE_PPC64X_FUNCDESC(main, _main<>) +// actually a function descriptor for _main<>(SB) +TEXT _rt0_ppc64_linux(SB),NOSPLIT,$0 + DWORD $_main<>(SB) + DWORD $0 + DWORD $0 + +TEXT main(SB),NOSPLIT,$0 + DWORD $_main<>(SB) + DWORD $0 + DWORD $0 TEXT _main<>(SB),NOSPLIT,$-8 // In a statically linked binary, the stack contains argc, diff --git a/src/runtime/sys_linux_ppc64x.s b/src/runtime/sys_linux_ppc64x.s index d105585b7e8..32db3c6b507 100644 --- a/src/runtime/sys_linux_ppc64x.s +++ b/src/runtime/sys_linux_ppc64x.s @@ -447,12 +447,7 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 MOVD 24(R1), R2 RET -#ifdef GO_PPC64X_HAS_FUNCDESC -DEFINE_PPC64X_FUNCDESC(runtime·sigtramp, sigtramp<>) -// cgo isn't supported on ppc64, but we need to supply a cgoSigTramp function. -DEFINE_PPC64X_FUNCDESC(runtime·cgoSigtramp, sigtramp<>) -TEXT sigtramp<>(SB),NOSPLIT|NOFRAME|TOPFRAME,$0 -#else +#ifdef GOARCH_ppc64le // ppc64le doesn't need function descriptors // Save callee-save registers in the case of signal forwarding. // Same as on ARM64 https://golang.org/issue/31827 . @@ -461,6 +456,13 @@ TEXT sigtramp<>(SB),NOSPLIT|NOFRAME|TOPFRAME,$0 // a function pointer) as R2 may not be preserved when calling this // function. In those cases, the caller preserves their R2. TEXT runtime·sigtramp(SB),NOSPLIT|NOFRAME,$0 +#else +// function descriptor for the real sigtramp +TEXT runtime·sigtramp(SB),NOSPLIT|NOFRAME,$0 + DWORD $sigtramp<>(SB) + DWORD $0 + DWORD $0 +TEXT sigtramp<>(SB),NOSPLIT|NOFRAME|TOPFRAME,$0 #endif // This is called with ELF calling conventions. Convert to Go. // Allocate space for argument storage to call runtime.sigtrampgo. @@ -489,6 +491,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT|NOFRAME,$0 RET #ifdef GOARCH_ppc64le +// ppc64le doesn't need function descriptors TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0 // The stack unwinder, presumably written in C, may not be able to // handle Go frame correctly. So, this function is NOFRAME, and we @@ -583,6 +586,14 @@ sigtrampnog: MOVD R12, CTR MOVD R10, LR // restore LR JMP (CTR) +#else +// function descriptor for the real sigtramp +TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0 + DWORD $cgoSigtramp<>(SB) + DWORD $0 + DWORD $0 +TEXT cgoSigtramp<>(SB),NOSPLIT,$0 + JMP sigtramp<>(SB) #endif // Used by cgoSigtramp to inspect without clobbering R30/R31 via runtime.load_g.