runtime/cgo: fix crosscall2 on ppc64x

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>
This commit is contained in:
Lynn Boger 2021-05-12 12:11:03 -05:00
parent ce92a2023c
commit bade680867
2 changed files with 15 additions and 4 deletions

View 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")

View file

@ -12,17 +12,20 @@
// 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