aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorClément Chigot <clement.chigot@atos.net>2019-02-20 16:52:35 +0100
committerIan Lance Taylor <iant@golang.org>2019-03-19 03:18:05 +0000
commit0cd74d1f1181c113352476d2913141e7cc88abc2 (patch)
tree8744f99db8f6d21748b1930cfc23d5344c92a57e /src/runtime
parentca36af215f78b670000b31e7573f0fcf0c5de594 (diff)
downloadgo-0cd74d1f1181c113352476d2913141e7cc88abc2.tar.xz
cmd, runtime: fix C trampolines on aix/ppc64
C trampolines are made by fixup CSECTS which are added between two symbols. If such CSECTS is added inside Go functions, all method offsets stored in moduledatas will be wrong. In order to prevent this, every C code is moved at the end of the executable and long calls are created for GO functions called by C code. The main function can't longer be made in Go as AIX __start isn't using a long call to branch on it. Therefore, a main is defined on runtime/cgo. Change-Id: I214b18decdb83107cf7325b298609eef9f9d1330 Reviewed-on: https://go-review.googlesource.com/c/go/+/164010 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/asm_ppc64x.s7
-rw-r--r--src/runtime/cgo/callbacks_aix.go10
-rw-r--r--src/runtime/cgo/gcc_aix_ppc64.S4
-rw-r--r--src/runtime/cgo/gcc_aix_ppc64.c22
4 files changed, 41 insertions, 2 deletions
diff --git a/src/runtime/asm_ppc64x.s b/src/runtime/asm_ppc64x.s
index 9ac83e5590..d7fc66bda1 100644
--- a/src/runtime/asm_ppc64x.s
+++ b/src/runtime/asm_ppc64x.s
@@ -113,6 +113,7 @@ TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
RET
+// Any changes must be reflected to runtime/cgo/gcc_aix_ppc64.S:.crosscall_ppc64
TEXT _cgo_reginit(SB),NOSPLIT|NOFRAME,$0-0
// crosscall_ppc64 and crosscall2 need to reginit, but can't
// get at the 'runtime.reginit' symbol.
@@ -847,7 +848,13 @@ TEXT runtime·return0(SB), NOSPLIT, $0
// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
// Must obey the gcc calling convention.
+#ifdef GOOS_aix
+// On AIX, _cgo_topofstack is defined in runtime/cgo, because it must
+// be a longcall in order to prevent trampolines from ld.
+TEXT __cgo_topofstack(SB),NOSPLIT|NOFRAME,$0
+#else
TEXT _cgo_topofstack(SB),NOSPLIT|NOFRAME,$0
+#endif
// g (R30) and R31 are callee-save in the C ABI, so save them
MOVD g, R4
MOVD R31, R5
diff --git a/src/runtime/cgo/callbacks_aix.go b/src/runtime/cgo/callbacks_aix.go
new file mode 100644
index 0000000000..26654931da
--- /dev/null
+++ b/src/runtime/cgo/callbacks_aix.go
@@ -0,0 +1,10 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cgo
+
+// These functions must be exported in order to perform
+// longcall on cgo programs (cf gcc_aix_ppc64.c).
+// go:cgo_export_static __cgo_topofstack
+// go:cgo_export_static runtime.rt0_go
diff --git a/src/runtime/cgo/gcc_aix_ppc64.S b/src/runtime/cgo/gcc_aix_ppc64.S
index bff6dd1999..a00fae24d2 100644
--- a/src/runtime/cgo/gcc_aix_ppc64.S
+++ b/src/runtime/cgo/gcc_aix_ppc64.S
@@ -31,8 +31,8 @@ crosscall_ppc64:
stdu 1, -296(1)
// Set up Go ABI constant registers
- bl ._cgo_reginit
- nop
+ // Must match _cgo_reginit in runtime package.
+ xor 0, 0, 0
// Restore g pointer (r30 in Go ABI, which may have been clobbered by C)
mr 30, 4
diff --git a/src/runtime/cgo/gcc_aix_ppc64.c b/src/runtime/cgo/gcc_aix_ppc64.c
new file mode 100644
index 0000000000..d54c0ff32d
--- /dev/null
+++ b/src/runtime/cgo/gcc_aix_ppc64.c
@@ -0,0 +1,22 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build aix
+// +build ppc64 ppc64le
+
+/*
+ * On AIX, call to _cgo_topofstack and Go main are forced to be a longcall.
+ * Without it, ld might add trampolines in the middle of .text section
+ * to reach these functions which are normally declared in runtime package.
+ */
+extern int __attribute__((longcall)) __cgo_topofstack(void);
+extern int __attribute__((longcall)) runtime_rt0_go(int argc, char **argv);
+
+int _cgo_topofstack(void) {
+ return __cgo_topofstack();
+}
+
+int main(int argc, char **argv) {
+ return runtime_rt0_go(argc, argv);
+}