cmd/link: canonicalize the "package" of dupok text symbols

Dupok symbols may be defined in multiple packages. Its associated
package is chosen sort of arbitrarily (the first containing package
that the linker loads). Canonicalize its package to the package
with which it will be laid down in text, which is the first package
in dependency order that defines the symbol. So later passes (for
example, trampoline insertion pass) know that the dupok symbol
is laid down along with the package.

Fixes #19764.

Change-Id: I7cbc7474ff3016d5069c8b7be04af934abab8bc3
Reviewed-on: https://go-review.googlesource.com/39150
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
Cherry Zhang 2017-03-31 07:14:16 -04:00
parent 78f6622b81
commit a1cedf0842
4 changed files with 44 additions and 0 deletions

View file

@ -647,6 +647,12 @@ func (ctxt *Link) loadlib() {
if !s.Attr.OnList() {
ctxt.Textp = append(ctxt.Textp, s)
s.Attr |= AttrOnList
// dupok symbols may be defined in multiple packages. its
// associated package is chosen sort of arbitrarily (the
// first containing package that the linker loads). canonicalize
// it here to the package with which it will be laid down
// in text.
s.File = pathtoprefix(lib.Pkg)
}
}
}

View file

@ -0,0 +1,15 @@
// 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.
package a
type T struct{ _ int }
func (t T) M() {}
type I interface { M() }
func F() {
var t I = &T{}
t.M() // call to the wrapper (*T).M
}

View file

@ -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.
package main
import "./a"
func main() {
var x a.I = &a.T{}
x.M() // call to the wrapper (*T).M
a.F() // make sure a.F is not dead, which also calls (*T).M inside package a
}

View file

@ -0,0 +1,10 @@
// rundir
// 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.
// Issue 19764: test that the linker's trampoline insertion
// pass is happy with direct calls to interface wrappers that
// may be defined in multiple packages.
package ignore