]> Cypherpunks repositories - gostls13.git/commitdiff
runtime/cgo: fix crosscall2 on ppc64x
authorLynn Boger <laboger@linux.vnet.ibm.com>
Wed, 12 May 2021 17:11:03 +0000 (12:11 -0500)
committerLynn Boger <laboger@linux.vnet.ibm.com>
Mon, 17 May 2021 15:57:52 +0000 (15:57 +0000)
Some uses of crosscall2 did not work on ppc64le and probably
aix-ppc64. In particular, if there was a main program compiled
with -buildmode=pie and used a plugin which invoked crosscall2,
then failures could occur due to R2 getting set incorrectly along the
way. The problem was due to R2 being saved on the caller's
stack; it is now saved on the crosscall2 stack. More details can be
found in the issue.

This adds a testcase where the main program is built with pie
and the plugin invokes crosscall2.

This also changes the save of the CR bits from MOVD to MOVW as
it should be.

Fixes #43228

Change-Id: Ib5673e25a2ec5ee46bf9a1ffb0cb1f3ef5449086
Reviewed-on: https://go-review.googlesource.com/c/go/+/319489
Run-TryBot: Lynn Boger <laboger@linux.vnet.ibm.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Trust: Heschi Kreinick <heschi@google.com>

misc/cgo/testplugin/plugin_test.go
src/runtime/cgo/asm_ppc64x.s

index 28a8c669c0790db26f74b6e7053f30951d763e54..a6accc1dfbba9e76cd674735618b9a4f8f9793b9 100644 (file)
@@ -263,6 +263,13 @@ func TestIssue25756(t *testing.T) {
        }
 }
 
+// Test with main using -buildmode=pie with plugin for issue #43228
+func TestIssue25756pie(t *testing.T) {
+       goCmd(t, "build", "-buildmode=plugin", "-o", "life.so", "./issue25756/plugin")
+       goCmd(t, "build", "-buildmode=pie", "-o", "issue25756pie.exe", "./issue25756/main.go")
+       run(t, "./issue25756pie.exe")
+}
+
 func TestMethod(t *testing.T) {
        // Exported symbol's method must be live.
        goCmd(t, "build", "-buildmode=plugin", "-o", "plugin.so", "./method/plugin.go")
index 9dec8d04ce12292bd5ed9ec1098d2ee82e7f2800..187b2d42f630d34c68f8cd90cfcf6bff3ef43260 100644 (file)
 // func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
 // Saves C callee-saved registers and calls cgocallback with three arguments.
 // fn is the PC of a func(a unsafe.Pointer) function.
+// The value of R2 is saved on the new stack frame, and not
+// the caller's frame due to issue #43228.
 TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
        // Start with standard C stack frame layout and linkage
        MOVD    LR, R0
        MOVD    R0, 16(R1)      // Save LR in caller's frame
        MOVW    CR, R0          // Save CR in caller's frame
-       MOVD    R0, 8(R1)
-       MOVD    R2, 24(R1)      // Save TOC in caller's frame
+       MOVW    R0, 8(R1)
 
        BL      saveregs2<>(SB)
 
        MOVDU   R1, (-288-3*8-FIXED_FRAME)(R1)
+       // Save the caller's R2
+       MOVD    R2, 24(R1)
 
        // Initialize Go ABI environment
        BL      runtime·reginit(SB)
@@ -41,12 +44,13 @@ TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
        MOVD    R6, FIXED_FRAME+16(R1)  // ctxt uintptr
        BL      runtime·cgocallback(SB)
 
+       // Restore the caller's R2
+       MOVD    24(R1), R2
        ADD     $(288+3*8+FIXED_FRAME), R1
 
        BL      restoreregs2<>(SB)
 
-       MOVD    24(R1), R2
-       MOVD    8(R1), R0
+       MOVW    8(R1), R0
        MOVFL   R0, $0xff
        MOVD    16(R1), R0
        MOVD    R0, LR