1
0
mirror of https://github.com/golang/go synced 2024-11-18 15:44:41 -07:00

cmd/go: use alternate debug_modinfo recipe for gccgo

Use a different recipe for capturing debug modinfo if we're compiling
with the gccgo toolchain, to avoid applying a go:linkname directive to
a variable (not supported by gccgo).

Fixes #30344.

Change-Id: I9ce3d42c3bbb809fd68b140f56f9bbe3406c351b
Reviewed-on: https://go-review.googlesource.com/c/go/+/171768
Reviewed-by: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Than McIntosh 2019-04-12 09:47:43 -04:00
parent 7987238d9c
commit baf7d95350
3 changed files with 23 additions and 5 deletions

View File

@ -40,7 +40,7 @@ var (
ModPackageModuleInfo func(path string) *modinfo.ModulePublic // return module info for Package struct
ModImportPaths func(args []string) []*search.Match // expand import paths
ModPackageBuildInfo func(main string, deps []string) string // return module info to embed in binary
ModInfoProg func(info string) []byte // wrap module info in .go code for binary
ModInfoProg func(info string, isgccgo bool) []byte // wrap module info in .go code for binary
ModImportFromFiles func([]string) // update go.mod to add modules for imports in these files
ModDirImportPath func(string) string // return effective import path for directory
)

View File

@ -249,16 +249,34 @@ func findModule(target, path string) module.Version {
panic("unreachable")
}
func ModInfoProg(info string) []byte {
func ModInfoProg(info string, isgccgo bool) []byte {
// Inject a variable with the debug information as runtime.modinfo,
// but compile it in package main so that it is specific to the binary.
// The variable must be a literal so that it will have the correct value
// before the initializer for package main runs.
//
// The runtime startup code refers to the variable, which keeps it live in all binaries.
return []byte(fmt.Sprintf(`package main
// The runtime startup code refers to the variable, which keeps it live
// in all binaries.
//
// Note: we use an alternate recipe below for gccgo (based on an
// init function) due to the fact that gccgo does not support
// applying a "//go:linkname" directive to a variable. This has
// drawbacks in that other packages may want to look at the module
// info in their init functions (see issue 29628), which won't
// work for gccgo. See also issue 30344.
if !isgccgo {
return []byte(fmt.Sprintf(`package main
import _ "unsafe"
//go:linkname __debug_modinfo__ runtime.modinfo
var __debug_modinfo__ = %q
`, string(infoStart)+info+string(infoEnd)))
} else {
return []byte(fmt.Sprintf(`package main
import _ "unsafe"
//go:linkname __set_debug_modinfo__ runtime..z2fdebug.setmodinfo
func __set_debug_modinfo__(string)
func init() { __set_debug_modinfo__(%q) }
`, string(infoStart)+info+string(infoEnd)))
}
}

View File

@ -663,7 +663,7 @@ func (b *Builder) build(a *Action) (err error) {
}
if p.Internal.BuildInfo != "" && cfg.ModulesEnabled {
if err := b.writeFile(objdir+"_gomod_.go", load.ModInfoProg(p.Internal.BuildInfo)); err != nil {
if err := b.writeFile(objdir+"_gomod_.go", load.ModInfoProg(p.Internal.BuildInfo, cfg.BuildToolchainName == "gccgo")); err != nil {
return err
}
gofiles = append(gofiles, objdir+"_gomod_.go")