Skip to content

Commit 660620d

Browse files
committed
cmd/link: avoid deadcode of global map vars for programs using plugins
If a program imports the plugin package, the mechanisms in place for detecting and deleting unused global map variables are no longer safe, since it's possibly for a given global map var to be unreferenced in the main program but referenced by a plugin. This patch changes the linker to test for plugin use and to avoid removing any unused global map variables if the main program could possibly load up a plugin. Fixes #62430. Change-Id: Ie00b18b681cb0d259e3c859ac947ade5778cd6c8 Reviewed-on: https://go-review.googlesource.com/c/go/+/526115 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Cherry Mui <[email protected]>
1 parent 3466e57 commit 660620d

4 files changed

Lines changed: 73 additions & 4 deletions

File tree

src/cmd/cgo/internal/testplugin/plugin_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,3 +388,10 @@ func TestSymbolNameMangle(t *testing.T) {
388388
globalSkip(t)
389389
goCmd(t, "build", "-buildmode=plugin", "-o", "mangle.so", "./mangle/plugin.go")
390390
}
391+
392+
func TestIssue62430(t *testing.T) {
393+
globalSkip(t)
394+
goCmd(t, "build", "-buildmode=plugin", "-o", "issue62430.so", "./issue62430/plugin.go")
395+
goCmd(t, "build", "-o", "issue62430.exe", "./issue62430/main.go")
396+
run(t, "./issue62430.exe")
397+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2023 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// Issue 62430: a program that uses plugins may appear
6+
// to have no references to an initialized global map variable defined
7+
// in some stdlib package (ex: unicode), however there
8+
// may be references to that map var from a plugin that
9+
// gets loaded.
10+
11+
package main
12+
13+
import (
14+
"fmt"
15+
"plugin"
16+
"unicode"
17+
)
18+
19+
func main() {
20+
p, err := plugin.Open("issue62430.so")
21+
if err != nil {
22+
panic(err)
23+
}
24+
s, err := p.Lookup("F")
25+
if err != nil {
26+
panic(err)
27+
}
28+
29+
f := s.(func(string) *unicode.RangeTable)
30+
if f("C") == nil {
31+
panic("unicode.Categories not properly initialized")
32+
} else {
33+
fmt.Println("unicode.Categories properly initialized")
34+
}
35+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package main
2+
3+
import (
4+
"unicode"
5+
)
6+
7+
func F(s string) *unicode.RangeTable {
8+
return unicode.Categories[s]
9+
}
10+
11+
func main() {}

src/cmd/link/internal/ld/deadcode.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,26 @@ func (d *deadcodePass) flood() {
143143
methods = methods[:0]
144144
for i := 0; i < relocs.Count(); i++ {
145145
r := relocs.At(i)
146-
// When build with "-linkshared", we can't tell if the interface
147-
// method in itab will be used or not. Ignore the weak attribute.
148-
if r.Weak() && !(d.ctxt.linkShared && d.ldr.IsItab(symIdx)) {
149-
continue
146+
if r.Weak() {
147+
convertWeakToStrong := false
148+
// When build with "-linkshared", we can't tell if the
149+
// interface method in itab will be used or not.
150+
// Ignore the weak attribute.
151+
if d.ctxt.linkShared && d.ldr.IsItab(symIdx) {
152+
convertWeakToStrong = true
153+
}
154+
// If the program uses plugins, we can no longer treat
155+
// relocs from pkg init functions to outlined map init
156+
// fragments as weak, since doing so can cause package
157+
// init clashes between the main program and the
158+
// plugin. See #62430 for more details.
159+
if d.ctxt.canUsePlugins && r.Type().IsDirectCall() {
160+
convertWeakToStrong = true
161+
}
162+
if !convertWeakToStrong {
163+
// skip this reloc
164+
continue
165+
}
150166
}
151167
t := r.Type()
152168
switch t {

0 commit comments

Comments
 (0)