1
0
mirror of https://github.com/golang/go synced 2024-09-30 17:28:32 -06:00

cmd/link: use IMAGE_SYM_CLASS_STATIC for local symbols

Sometimes asm code in 2 different packages name its global
symbols with the same name. When these symbols are passed
to gcc, it refuses to link them thinking they are duplicate.
Mark these symbols with IMAGE_SYM_CLASS_STATIC.

Fixes #19198.

Change-Id: Ia5f59ede47354a2b48ce60b7d406c9f097ff2000
Reviewed-on: https://go-review.googlesource.com/37810
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Alex Brainman 2017-03-05 19:57:26 +11:00
parent 6491496d10
commit d3f5e36917
2 changed files with 49 additions and 1 deletions

View File

@ -3803,3 +3803,47 @@ func TestFFLAGS(t *testing.T) {
tg.grepStderr("no-such-fortran-flag", `missing expected "-no-such-fortran-flag"`)
}
// Issue 19198.
// This is really a cmd/link issue but this is a convenient place to test it.
func TestDuplicateGlobalAsmSymbols(t *testing.T) {
if runtime.GOARCH != "386" && runtime.GOARCH != "amd64" {
t.Skipf("skipping test on %s", runtime.GOARCH)
}
if !canCgo {
t.Skip("skipping because cgo not enabled")
}
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
asm := `
#include "textflag.h"
DATA sym<>+0x0(SB)/8,$0
GLOBL sym<>(SB),(NOPTR+RODATA),$8
TEXT ·Data(SB),NOSPLIT,$0
MOVB sym<>(SB), AX
MOVB AX, ret+0(FP)
RET
`
tg.tempFile("go/src/a/a.s", asm)
tg.tempFile("go/src/a/a.go", `package a; func Data() uint8`)
tg.tempFile("go/src/b/b.s", asm)
tg.tempFile("go/src/b/b.go", `package b; func Data() uint8`)
tg.tempFile("go/src/p/p.go", `
package main
import "a"
import "b"
import "C"
func main() {
_ = a.Data() + b.Data()
}
`)
tg.setenv("GOPATH", tg.path("go"))
exe := filepath.Join(tg.tempdir, "p.exe")
tg.creatingTemp(exe)
tg.run("build", "-o", exe, "p")
}

View File

@ -1040,7 +1040,11 @@ func writePESymTableRecords(ctxt *Link) int {
typ = IMAGE_SYM_DTYPE_ARRAY<<8 + IMAGE_SYM_TYPE_STRUCT
typ = 0x0308 // "array of structs"
}
writeOneSymbol(s, value, sect, typ, IMAGE_SYM_CLASS_EXTERNAL)
class := IMAGE_SYM_CLASS_EXTERNAL
if s.Version != 0 || (s.Type&obj.SHIDDEN != 0) || s.Attr.Local() {
class = IMAGE_SYM_CLASS_STATIC
}
writeOneSymbol(s, value, sect, typ, uint8(class))
}
if Linkmode == LinkExternal {