diff options
Diffstat (limited to 'src/runtime/cgo/asm_ppc64x.s')
-rw-r--r-- | src/runtime/cgo/asm_ppc64x.s | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/src/runtime/cgo/asm_ppc64x.s b/src/runtime/cgo/asm_ppc64x.s index cba053deb7..c258c7c2a0 100644 --- a/src/runtime/cgo/asm_ppc64x.s +++ b/src/runtime/cgo/asm_ppc64x.s @@ -8,6 +8,25 @@ #include "asm_ppc64x.h" #include "abi_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 + MOVD R6, (R5) + RET + // 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. @@ -27,8 +46,12 @@ TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0 #ifdef GO_PPC64X_HAS_FUNCDESC // Load the real entry address from the first slot of the function descriptor. + // The first argument fn might be null, that means dropm in pthread key destructor. + CMP R3, $0 + BEQ nil_fn MOVD 8(R3), R2 MOVD (R3), R3 +nil_fn: #endif MOVD R3, FIXED_FRAME+0(R1) // fn unsafe.Pointer MOVD R4, FIXED_FRAME+8(R1) // a unsafe.Pointer |