mirror of
https://github.com/golang/go
synced 2024-11-26 03:37:57 -07:00
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:
parent
ce92a2023c
commit
bade680867
@ -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) {
|
func TestMethod(t *testing.T) {
|
||||||
// Exported symbol's method must be live.
|
// Exported symbol's method must be live.
|
||||||
goCmd(t, "build", "-buildmode=plugin", "-o", "plugin.so", "./method/plugin.go")
|
goCmd(t, "build", "-buildmode=plugin", "-o", "plugin.so", "./method/plugin.go")
|
||||||
|
@ -12,17 +12,20 @@
|
|||||||
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
|
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
|
||||||
// Saves C callee-saved registers and calls cgocallback with three arguments.
|
// Saves C callee-saved registers and calls cgocallback with three arguments.
|
||||||
// fn is the PC of a func(a unsafe.Pointer) function.
|
// 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
|
TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
|
||||||
// Start with standard C stack frame layout and linkage
|
// Start with standard C stack frame layout and linkage
|
||||||
MOVD LR, R0
|
MOVD LR, R0
|
||||||
MOVD R0, 16(R1) // Save LR in caller's frame
|
MOVD R0, 16(R1) // Save LR in caller's frame
|
||||||
MOVW CR, R0 // Save CR in caller's frame
|
MOVW CR, R0 // Save CR in caller's frame
|
||||||
MOVD R0, 8(R1)
|
MOVW R0, 8(R1)
|
||||||
MOVD R2, 24(R1) // Save TOC in caller's frame
|
|
||||||
|
|
||||||
BL saveregs2<>(SB)
|
BL saveregs2<>(SB)
|
||||||
|
|
||||||
MOVDU R1, (-288-3*8-FIXED_FRAME)(R1)
|
MOVDU R1, (-288-3*8-FIXED_FRAME)(R1)
|
||||||
|
// Save the caller's R2
|
||||||
|
MOVD R2, 24(R1)
|
||||||
|
|
||||||
// Initialize Go ABI environment
|
// Initialize Go ABI environment
|
||||||
BL runtime·reginit(SB)
|
BL runtime·reginit(SB)
|
||||||
@ -41,12 +44,13 @@ TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
|
|||||||
MOVD R6, FIXED_FRAME+16(R1) // ctxt uintptr
|
MOVD R6, FIXED_FRAME+16(R1) // ctxt uintptr
|
||||||
BL runtime·cgocallback(SB)
|
BL runtime·cgocallback(SB)
|
||||||
|
|
||||||
|
// Restore the caller's R2
|
||||||
|
MOVD 24(R1), R2
|
||||||
ADD $(288+3*8+FIXED_FRAME), R1
|
ADD $(288+3*8+FIXED_FRAME), R1
|
||||||
|
|
||||||
BL restoreregs2<>(SB)
|
BL restoreregs2<>(SB)
|
||||||
|
|
||||||
MOVD 24(R1), R2
|
MOVW 8(R1), R0
|
||||||
MOVD 8(R1), R0
|
|
||||||
MOVFL R0, $0xff
|
MOVFL R0, $0xff
|
||||||
MOVD 16(R1), R0
|
MOVD 16(R1), R0
|
||||||
MOVD R0, LR
|
MOVD R0, LR
|
||||||
|
Loading…
Reference in New Issue
Block a user