Commit d3f5e369 authored by Alex Brainman's avatar Alex Brainman

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/37810Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 6491496d
......@@ -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")
}
......@@ -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 {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment