From f1c4444dfcca5967543d43190b6c80c9254b99ac Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Tue, 16 Dec 2014 17:14:00 -0500 Subject: [PATCH] runtime: set up C TLS and save g to it on ppc64 Cgo will need this for calls from C to Go and for handling signals that may occur in C code. Change-Id: I50cc4caf17cd142bff501e7180a1e27721463ada Reviewed-on: https://go-review.googlesource.com/2008 Reviewed-by: Russ Cox --- src/runtime/arch1_ppc64.go | 2 +- src/runtime/arch1_ppc64le.go | 2 +- src/runtime/asm_ppc64x.s | 8 +++++ src/runtime/rt0_linux_ppc64le.s | 2 ++ src/runtime/tls_ppc64x.s | 56 +++++++++++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 src/runtime/tls_ppc64x.s diff --git a/src/runtime/arch1_ppc64.go b/src/runtime/arch1_ppc64.go index 01e2b70f95..6996d0fac0 100644 --- a/src/runtime/arch1_ppc64.go +++ b/src/runtime/arch1_ppc64.go @@ -8,7 +8,7 @@ const ( thechar = '9' _BigEndian = 1 _CacheLineSize = 64 - _RuntimeGogoBytes = 64 + _RuntimeGogoBytes = 72 _PhysPageSize = 65536 _PCQuantum = 4 _Int64Align = 8 diff --git a/src/runtime/arch1_ppc64le.go b/src/runtime/arch1_ppc64le.go index 6580732a37..7d5dac46a0 100644 --- a/src/runtime/arch1_ppc64le.go +++ b/src/runtime/arch1_ppc64le.go @@ -8,7 +8,7 @@ const ( thechar = '9' _BigEndian = 0 _CacheLineSize = 64 - _RuntimeGogoBytes = 64 + _RuntimeGogoBytes = 72 _PhysPageSize = 65536 _PCQuantum = 4 _Int64Align = 8 diff --git a/src/runtime/asm_ppc64x.s b/src/runtime/asm_ppc64x.s index 8ec051d5dd..a2aba632e9 100644 --- a/src/runtime/asm_ppc64x.s +++ b/src/runtime/asm_ppc64x.s @@ -10,6 +10,8 @@ #include "textflag.h" TEXT runtime·rt0_go(SB),NOSPLIT,$0 + // R1 = stack; R3 = argc; R4 = argv; R13 = C TLS base pointer + // initialize essential registers BL runtime·reginit(SB) @@ -102,6 +104,8 @@ TEXT runtime·gosave(SB), NOSPLIT, $-8-8 TEXT runtime·gogo(SB), NOSPLIT, $-8-8 MOVD buf+0(FP), R5 MOVD gobuf_g(R5), g // make sure g is not nil + BL runtime·save_g(SB) + MOVD 0(g), R4 MOVD gobuf_sp(R5), R1 MOVD gobuf_lr(R5), R31 @@ -133,6 +137,7 @@ TEXT runtime·mcall(SB), NOSPLIT, $-8-8 MOVD g, R3 MOVD g_m(g), R8 MOVD m_g0(R8), g + BL runtime·save_g(SB) CMP g, R3 BNE 2(PC) BR runtime·badmcall(SB) @@ -191,6 +196,7 @@ switch: // switch to g0 MOVD R5, g + BL runtime·save_g(SB) MOVD (g_sched+gobuf_sp)(g), R3 // make it look like mstart called systemstack on g0, to stop traceback SUB $8, R3 @@ -206,6 +212,7 @@ switch: // switch back to g MOVD g_m(g), R3 MOVD m_curg(R3), g + BL runtime·save_g(SB) MOVD (g_sched+gobuf_sp)(g), R1 MOVD R0, (g_sched+gobuf_sp)(g) RETURN @@ -259,6 +266,7 @@ TEXT runtime·morestack(SB),NOSPLIT,$-8-0 // Call newstack on m->g0's stack. MOVD m_g0(R7), g + BL runtime·save_g(SB) MOVD (g_sched+gobuf_sp)(g), R1 BL runtime·newstack(SB) diff --git a/src/runtime/rt0_linux_ppc64le.s b/src/runtime/rt0_linux_ppc64le.s index a3b3cea0b5..dda29ab3a0 100644 --- a/src/runtime/rt0_linux_ppc64le.s +++ b/src/runtime/rt0_linux_ppc64le.s @@ -6,6 +6,8 @@ TEXT _rt0_ppc64le_linux(SB),NOSPLIT,$0 TEXT _main<>(SB),NOSPLIT,$-8 MOVD 0(R1), R3 // argc ADD $8, R1, R4 // argv + MOVD $runtime·tls0(SB), R13 // TLS + ADD $0x7000, R13 BR main(SB) TEXT main(SB),NOSPLIT,$-8 diff --git a/src/runtime/tls_ppc64x.s b/src/runtime/tls_ppc64x.s new file mode 100644 index 0000000000..fa1f9ac6f0 --- /dev/null +++ b/src/runtime/tls_ppc64x.s @@ -0,0 +1,56 @@ +// Copyright 2014 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 ppc64 ppc64le + +#include "go_asm.h" +#include "go_tls.h" +#include "funcdata.h" +#include "textflag.h" + +// We have to resort to TLS variable to save g (R30). +// One reason is that external code might trigger +// SIGSEGV, and our runtime.sigtramp don't even know we +// are in external code, and will continue to use R30, +// this might well result in another SIGSEGV. + +// save_g saves the g register into pthread-provided +// thread-local memory, so that we can call externally compiled +// ppc64 code that will overwrite this register. +// +// If !iscgo, this is a no-op. +TEXT runtime·save_g(SB),NOSPLIT,$-8-0 + MOVB runtime·iscgo(SB), R31 + CMP R31, $0 + BEQ nocgo + + // $runtime.tlsg(SB) is a special linker symbol. + // It is the offset from the start of TLS to our + // thread-local storage for g. + MOVD $runtime·tlsg(SB), R31 + ADD R13, R31 + // The actual TLS base is 0x7000 below R13 + SUB $0x7000, R31 + + // Store g in TLS + MOVD g, 0(R31) + +nocgo: + RET + +// load_g loads the g register from pthread-provided +// thread-local memory, for use after calling externally compiled +// ppc64 code that overwrote those registers. +// +// This is never called directly from C code (it doesn't have to +// follow the C ABI), but it may be called from a C context, where the +// usual Go registers aren't set up. +TEXT runtime·load_g(SB),NOSPLIT,$-8-0 + MOVD $runtime·tlsg(SB), R31 + // R13 is the C ABI TLS base pointer + 0x7000 + ADD R13, R31 + SUB $0x7000, R31 + + MOVD 0(R31), g + RET -- 2.50.0