]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: use alternate debug_modinfo recipe for gccgo
authorThan McIntosh <thanm@google.com>
Fri, 12 Apr 2019 13:47:43 +0000 (09:47 -0400)
committerThan McIntosh <thanm@google.com>
Wed, 18 Sep 2019 17:41:44 +0000 (17:41 +0000)
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>

src/cmd/go/internal/load/pkg.go
src/cmd/go/internal/modload/build.go
src/cmd/go/internal/work/exec.go

index 27efc7c04aaac3282bd78fc96fa4418706e1a32b..daaa3ab0c1adeef2afc892c7648d1cbf7241d049 100644 (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
 )
index ff42516c807ddce7ef94f2702849c8060d9afe5b..f8dc0c84ff308def875a3b647713d116aab35a04 100644 (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)))
+       }
 }
index 626cacfe992d4e1bbab30ef5c3af9863201e35a3..b75c61b6f2d8147812128814bf936871586fbb95 100644 (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")