aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/cgo/internal/testshared/testdata/dep2/dep2.go6
-rw-r--r--src/cmd/cgo/internal/testshared/testdata/depBase/dep.go16
-rw-r--r--src/cmd/cgo/internal/testshared/testdata/depBaseInternal/dep.go13
-rw-r--r--src/cmd/link/internal/ld/deadcode.go1
-rw-r--r--src/cmd/link/internal/ld/inittask.go38
5 files changed, 62 insertions, 12 deletions
diff --git a/src/cmd/cgo/internal/testshared/testdata/dep2/dep2.go b/src/cmd/cgo/internal/testshared/testdata/dep2/dep2.go
index 94f38cf507..18d774b5fc 100644
--- a/src/cmd/cgo/internal/testshared/testdata/dep2/dep2.go
+++ b/src/cmd/cgo/internal/testshared/testdata/dep2/dep2.go
@@ -2,6 +2,12 @@ package dep2
import "testshared/depBase"
+func init() {
+ if !depBase.Initialized {
+ panic("depBase not initialized")
+ }
+}
+
var W int = 1
var hasProg depBase.HasProg
diff --git a/src/cmd/cgo/internal/testshared/testdata/depBase/dep.go b/src/cmd/cgo/internal/testshared/testdata/depBase/dep.go
index e7cc7c81eb..a143fe2ff1 100644
--- a/src/cmd/cgo/internal/testshared/testdata/depBase/dep.go
+++ b/src/cmd/cgo/internal/testshared/testdata/depBase/dep.go
@@ -7,8 +7,24 @@ package depBase
import (
"os"
"reflect"
+
+ "testshared/depBaseInternal"
)
+// Issue 61973: indirect dependencies are not initialized.
+func init() {
+ if !depBaseInternal.Initialized {
+ panic("depBaseInternal not initialized")
+ }
+ if os.Stdout == nil {
+ panic("os.Stdout is nil")
+ }
+
+ Initialized = true
+}
+
+var Initialized bool
+
var SlicePtr interface{} = &[]int{}
var V int = 1
diff --git a/src/cmd/cgo/internal/testshared/testdata/depBaseInternal/dep.go b/src/cmd/cgo/internal/testshared/testdata/depBaseInternal/dep.go
new file mode 100644
index 0000000000..906bff09c4
--- /dev/null
+++ b/src/cmd/cgo/internal/testshared/testdata/depBaseInternal/dep.go
@@ -0,0 +1,13 @@
+// Copyright 2023 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.
+
+// depBaseInternal is only imported by depBase.
+
+package depBaseInternal
+
+var Initialized bool
+
+func init() {
+ Initialized = true
+}
diff --git a/src/cmd/link/internal/ld/deadcode.go b/src/cmd/link/internal/ld/deadcode.go
index a051e43401..70b4a7ca30 100644
--- a/src/cmd/link/internal/ld/deadcode.go
+++ b/src/cmd/link/internal/ld/deadcode.go
@@ -51,6 +51,7 @@ func (d *deadcodePass) init() {
s := loader.Sym(i)
d.mark(s, 0)
}
+ d.mark(d.ctxt.mainInittasks, 0)
return
}
diff --git a/src/cmd/link/internal/ld/inittask.go b/src/cmd/link/internal/ld/inittask.go
index 0699107cd0..c4c5beb55e 100644
--- a/src/cmd/link/internal/ld/inittask.go
+++ b/src/cmd/link/internal/ld/inittask.go
@@ -41,15 +41,21 @@ func (ctxt *Link) inittasks() {
switch ctxt.BuildMode {
case BuildModeExe, BuildModePIE, BuildModeCArchive, BuildModeCShared:
// Normally the inittask list will be run on program startup.
- ctxt.mainInittasks = ctxt.inittaskSym("main..inittask", "go:main.inittasks")
+ ctxt.mainInittasks = ctxt.inittaskSym([]string{"main..inittask"}, "go:main.inittasks")
case BuildModePlugin:
// For plugins, the list will be run on plugin load.
- ctxt.mainInittasks = ctxt.inittaskSym(fmt.Sprintf("%s..inittask", objabi.PathToPrefix(*flagPluginPath)), "go:plugin.inittasks")
+ ctxt.mainInittasks = ctxt.inittaskSym([]string{fmt.Sprintf("%s..inittask", objabi.PathToPrefix(*flagPluginPath))}, "go:plugin.inittasks")
// Make symbol local so multiple plugins don't clobber each other's inittask list.
ctxt.loader.SetAttrLocal(ctxt.mainInittasks, true)
case BuildModeShared:
- // Nothing to do. The inittask list will be built by
- // the final build (with the -linkshared option).
+ // For a shared library, all packages are roots.
+ var roots []string
+ for _, lib := range ctxt.Library {
+ roots = append(roots, fmt.Sprintf("%s..inittask", objabi.PathToPrefix(lib.Pkg)))
+ }
+ ctxt.mainInittasks = ctxt.inittaskSym(roots, "go:shlib.inittasks")
+ // Make symbol local so multiple plugins don't clobber each other's inittask list.
+ ctxt.loader.SetAttrLocal(ctxt.mainInittasks, true)
default:
Exitf("unhandled build mode %d", ctxt.BuildMode)
}
@@ -58,7 +64,7 @@ func (ctxt *Link) inittasks() {
// initialize the runtime_inittasks variable.
ldr := ctxt.loader
if ldr.Lookup("runtime.runtime_inittasks", 0) != 0 {
- t := ctxt.inittaskSym("runtime..inittask", "go:runtime.inittasks")
+ t := ctxt.inittaskSym([]string{"runtime..inittask"}, "go:runtime.inittasks")
// This slice header is already defined in runtime/proc.go, so we update it here with new contents.
sh := ldr.Lookup("runtime.runtime_inittasks", 0)
@@ -72,11 +78,17 @@ func (ctxt *Link) inittasks() {
}
// inittaskSym builds a symbol containing pointers to all the inittasks
-// that need to be run, given the root inittask symbol.
-func (ctxt *Link) inittaskSym(rootName, symName string) loader.Sym {
+// that need to be run, given a list of root inittask symbols.
+func (ctxt *Link) inittaskSym(rootNames []string, symName string) loader.Sym {
ldr := ctxt.loader
- root := ldr.Lookup(rootName, 0)
- if root == 0 {
+ var roots []loader.Sym
+ for _, n := range rootNames {
+ p := ldr.Lookup(n, 0)
+ if p != 0 {
+ roots = append(roots, p)
+ }
+ }
+ if len(roots) == 0 {
// Nothing to do
return 0
}
@@ -98,13 +110,15 @@ func (ctxt *Link) inittaskSym(rootName, symName string) loader.Sym {
// p's direct imports that have not yet been scheduled.
m := map[loader.Sym]int{}
- // Find all reachable inittask records from the root.
+ // Find all reachable inittask records from the roots.
// Keep track of the dependency edges between them in edges.
// Keep track of how many imports each package has in m.
// q is the list of found but not yet explored packages.
var q []loader.Sym
- m[root] = 0
- q = append(q, root)
+ for _, p := range roots {
+ m[p] = 0
+ q = append(q, p)
+ }
for len(q) > 0 {
x := q[len(q)-1]
q = q[:len(q)-1]