From: Russ Cox Date: Thu, 5 Oct 2017 15:11:29 +0000 (-0400) Subject: cmd/go, runtime/cgo: rewrite darwin/arm panicmem setup to avoid init function X-Git-Tag: go1.10beta1~862 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=69b0b3ad22c0127e199c94f2866577346efa1287;p=gostls13.git cmd/go, runtime/cgo: rewrite darwin/arm panicmem setup to avoid init function Init functions are problematic because we want cmd/link to be able to insert an import of runtime/cgo for external linking. For all the other systems that just means putting runtime/cgo into the binary. The linker is not set up to generate calls to init functions, and luckily this one can be avoided entirely. This means people don't have to import _ "runtime/cgo" in their iOS programs anymore. The linker's default import is now enough. This CL also adjusts cmd/go to record the linker's default import, now that the explicit import is gone. Change-Id: I81d23476663e03664f90d531c24db2e4f2e6c66b Reviewed-on: https://go-review.googlesource.com/68490 Run-TryBot: Russ Cox Reviewed-by: David Crawshaw TryBot-Result: Gobot Gobot --- diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go index b50074f0af..0d8e264eb7 100644 --- a/src/cmd/go/internal/cfg/cfg.go +++ b/src/cmd/go/internal/cfg/cfg.go @@ -131,7 +131,24 @@ func isGOROOT(path string) bool { // ExternalLinkingForced reports whether external linking is being // forced even for programs that do not use cgo. -func ExternalLinkingForced() bool { +func ExternalLinkingForced(inGoroot bool) bool { + // Some targets must use external linking even inside GOROOT. + switch BuildContext.GOOS { + case "android": + return true + case "darwin": + switch BuildContext.GOARCH { + case "arm", "arm64": + return true + } + } + + // Otherwise we disable forcing of external linking for GOROOT binaries. + // This is primarily for cgo, so we will be able to relax this soon. + if inGoroot { + return false + } + if !BuildContext.CgoEnabled { return false } @@ -151,5 +168,6 @@ func ExternalLinkingForced() bool { linkmodeExternal = true } } + return BuildBuildmode == "c-shared" || BuildBuildmode == "plugin" || pieCgo || BuildLinkshared || linkmodeExternal } diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go index 63e58c6247..dace766aed 100644 --- a/src/cmd/go/internal/load/pkg.go +++ b/src/cmd/go/internal/load/pkg.go @@ -946,7 +946,7 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { importPaths = append(importPaths, "syscall") } - if p.Name == "main" && !p.Goroot && cfg.ExternalLinkingForced() { + if p.Name == "main" && cfg.ExternalLinkingForced(p.Goroot) { importPaths = append(importPaths, "runtime/cgo") } diff --git a/src/cmd/go/internal/test/test.go b/src/cmd/go/internal/test/test.go index bdedd25651..c3810feb0d 100644 --- a/src/cmd/go/internal/test/test.go +++ b/src/cmd/go/internal/test/test.go @@ -815,16 +815,10 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin }, } - // The generated main also imports testing, regexp, os, and maybe runtime/cgo. + // The generated main also imports testing, regexp, and os. stk.Push("testmain") - forceCgo := false - if cfg.BuildContext.GOOS == "darwin" { - if cfg.BuildContext.GOARCH == "arm" || cfg.BuildContext.GOARCH == "arm64" { - forceCgo = true - } - } deps := testMainDeps - if cfg.ExternalLinkingForced() || forceCgo { + if cfg.ExternalLinkingForced(pmain.Goroot) { deps = str.StringList(deps, "runtime/cgo") } for _, dep := range deps { @@ -889,8 +883,6 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin recompileForTest(pmain, p, ptest) } - t.NeedCgo = forceCgo - for _, cp := range pmain.Internal.Imports { if len(cp.Internal.CoverVars) > 0 { t.Cover = append(t.Cover, coverInfo{cp, cp.Internal.CoverVars}) @@ -1319,7 +1311,6 @@ type testFuncs struct { NeedTest bool ImportXtest bool NeedXtest bool - NeedCgo bool Cover []coverInfo } @@ -1448,10 +1439,6 @@ import ( {{range $i, $p := .Cover}} _cover{{$i}} {{$p.Package.ImportPath | printf "%q"}} {{end}} - -{{if .NeedCgo}} - _ "runtime/cgo" -{{end}} ) var tests = []testing.InternalTest{ diff --git a/src/runtime/cgo/gcc_signal2_darwin_armx.c b/src/runtime/cgo/gcc_signal2_darwin_armx.c new file mode 100644 index 0000000000..6da623b3b1 --- /dev/null +++ b/src/runtime/cgo/gcc_signal2_darwin_armx.c @@ -0,0 +1,13 @@ +// Copyright 2017 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 lldb +// +build darwin +// +build arm arm64 + +// Used by gcc_signal_darwin_armx.c when doing the test build during cgo. +// We hope that for real binaries the definition provided by Go will take precedence +// and the linker will drop this .o file altogether, which is why this definition +// is all by itself in its own file. +void xx_cgo_panicmem(void) {} diff --git a/src/runtime/cgo/gcc_signal_darwin_armx.c b/src/runtime/cgo/gcc_signal_darwin_armx.c index a2d520bce8..3ab1d8b0d6 100644 --- a/src/runtime/cgo/gcc_signal_darwin_armx.c +++ b/src/runtime/cgo/gcc_signal_darwin_armx.c @@ -39,7 +39,8 @@ #include "libcgo.h" #include "libcgo_unix.h" -uintptr_t x_cgo_panicmem; +void xx_cgo_panicmem(void); +uintptr_t x_cgo_panicmem = (uintptr_t)xx_cgo_panicmem; static pthread_mutex_t mach_exception_handler_port_set_mu; static mach_port_t mach_exception_handler_port_set = MACH_PORT_NULL; diff --git a/src/runtime/cgo/gcc_signal_darwin_lldb.c b/src/runtime/cgo/gcc_signal_darwin_lldb.c index 12cc388400..54d91f6390 100644 --- a/src/runtime/cgo/gcc_signal_darwin_lldb.c +++ b/src/runtime/cgo/gcc_signal_darwin_lldb.c @@ -8,7 +8,5 @@ #include -uintptr_t x_cgo_panicmem; - void darwin_arm_init_thread_exception_port() {} void darwin_arm_init_mach_exception_handler() {} diff --git a/src/runtime/cgo/signal_darwin_armx.go b/src/runtime/cgo/signal_darwin_armx.go index 9f6741eb08..e1d9e54c46 100644 --- a/src/runtime/cgo/signal_darwin_armx.go +++ b/src/runtime/cgo/signal_darwin_armx.go @@ -7,29 +7,7 @@ package cgo -import "unsafe" - -//go:cgo_import_static x_cgo_panicmem -//go:linkname x_cgo_panicmem x_cgo_panicmem -var x_cgo_panicmem uintptr - -// use a pointer to avoid relocation of external symbol in __TEXT -// make linker happy -var _cgo_panicmem = &x_cgo_panicmem - -// TODO(crawshaw): move this into x_cgo_init, it will not run until -// runtime has finished loading, which may be after its use. -func init() { - *_cgo_panicmem = funcPC(panicmem) -} - -func funcPC(f interface{}) uintptr { - var ptrSize = unsafe.Sizeof(uintptr(0)) - return **(**uintptr)(add(unsafe.Pointer(&f), ptrSize)) -} - -func add(p unsafe.Pointer, x uintptr) unsafe.Pointer { - return unsafe.Pointer(uintptr(p) + x) -} +import _ "unsafe" +//go:cgo_export_static panicmem xx_cgo_panicmem func panicmem()