]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: consolidate function descriptor definitions on PPC64
authorPaul E. Murphy <murp@ibm.com>
Thu, 23 Mar 2023 15:41:31 +0000 (10:41 -0500)
committerPaul Murphy <murp@ibm.com>
Mon, 27 Mar 2023 22:17:55 +0000 (22:17 +0000)
This is a cleanup to allow a consistent definitions of a function
descriptor on code shared between AIX and Linux. They need to be
declared in slightly different ways, but we can hide that in one
macro.

And, update all usage.

Change-Id: I10f3580473db555b4fb4d2597b856f3a67d01a53
Reviewed-on: https://go-review.googlesource.com/c/go/+/478917
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Paul Murphy <murp@ibm.com>

src/runtime/asm_ppc64x.h
src/runtime/asm_ppc64x.s
src/runtime/cgo/asm_ppc64x.s
src/runtime/rt0_aix_ppc64.s
src/runtime/rt0_linux_ppc64.s
src/runtime/sys_linux_ppc64x.s

index cce5537a9cb59b7e060170a654d45099af13ff83..65870fe020fa3d40a7a8799aae567c79b629d464 100644 (file)
 
 #define FIXED_FRAME 32
 
-// aix/ppc64 uses XCOFF which has function descriptors.
+// 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.
 #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 has function descriptors.
+// 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.
 #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
index 7c866b4bc3367acdb71cf3fef8fe7092d14d3192..293683f41924c7390f2f296033b1a069c5db67a1 100644 (file)
@@ -771,26 +771,11 @@ TEXT runtime·setg(SB), NOSPLIT, $0-8
        BL      runtime·save_g(SB)
        RET
 
-#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
+#ifdef GO_PPC64X_HAS_FUNCDESC
+DEFINE_PPC64X_FUNCDESC(setg_gcc<>, _setg_gcc<>)
+TEXT _setg_gcc<>(SB),NOSPLIT|NOFRAME,$0-0
 #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.
index 8eb4a4215788656bbac898af8f8ffd2fbd36d67c..7752feb65047468c74f79e7d8c3b7b8f0a99e070 100644 (file)
@@ -7,26 +7,25 @@
 #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
-#ifdef GOARCH_ppc64
-       MOVD    $_crosscall2<>(SB), R6
-#else
-       MOVD    $crosscall2(SB), R6
-#endif
+       MOVD    CROSSCALL2_FPTR, R6
        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.
index 86fda5689967ab61b279261c811bb439471db8a4..1670a809862a2bdd0345171737804fa52112b2a4 100644 (file)
@@ -3,13 +3,11 @@
 // 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.
-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
-
+DEFINE_PPC64X_FUNCDESC(_rt0_ppc64_aix, __start<>)
 
 // The starting function must return in the loader to
 // initialise some libraries, especially libthread which
@@ -37,11 +35,7 @@ TEXT __start<>(SB),NOSPLIT,$-8
        BL _main(SB)
 
 
-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
-
+DEFINE_PPC64X_FUNCDESC(main, _main)
 TEXT _main(SB),NOSPLIT,$-8
        MOVD $runtime·rt0_go(SB), R12
        MOVD R12, CTR
@@ -181,10 +175,7 @@ done:
        MOVD    R0, LR
        RET
 
-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
+DEFINE_PPC64X_FUNCDESC(_rt0_ppc64_aix_lib_go, __rt0_ppc64_aix_lib_go)
 
 TEXT __rt0_ppc64_aix_lib_go(SB),NOSPLIT,$0
        MOVD    _rt0_ppc64_aix_lib_argc<>(SB), R3
index c9300a9caf602f8b3863b0b15e621ddfe4fe0955..f527170ed2848a1cc236b37b2f69fc1c63175f22 100644 (file)
@@ -3,17 +3,10 @@
 // license that can be found in the LICENSE file.
 
 #include "textflag.h"
+#include "asm_ppc64x.h"
 
-// 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
+DEFINE_PPC64X_FUNCDESC(_rt0_ppc64_linux, _main<>)
+DEFINE_PPC64X_FUNCDESC(main, _main<>)
 
 TEXT _main<>(SB),NOSPLIT,$-8
        // In a statically linked binary, the stack contains argc,
index ec9b966c8c3c80594f38148bc2cc2224f5ae2f32..44cd0e7b3e57f51cf44d0d8c1c09bf96ba6b8faa 100644 (file)
@@ -447,18 +447,16 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
        MOVD    24(R1), R2
        RET
 
-#ifdef GOARCH_ppc64le
+#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
 // 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 .
 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
        // Start with standard C stack frame layout and linkage.
        MOVD    LR, R0
@@ -627,7 +625,6 @@ TEXT sigtramp<>(SB),NOSPLIT|NOFRAME|TOPFRAME,$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
@@ -722,14 +719,6 @@ 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.