]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: use IMAGE_SYM_CLASS_STATIC for local symbols
authorAlex Brainman <alex.brainman@gmail.com>
Sun, 5 Mar 2017 08:57:26 +0000 (19:57 +1100)
committerAlex Brainman <alex.brainman@gmail.com>
Tue, 7 Mar 2017 03:26:47 +0000 (03:26 +0000)
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>

src/cmd/go/go_test.go
src/cmd/link/internal/ld/pe.go

index 2f8f36b162821db130ac57c25c2806bbb5a35bed..5786defb8b5deb43cb589a626a47d19efa6c50bb 100644 (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")
+}
index 77c86fecbd86ff6edc11a4382fdccc7d19119e11..79e7890a381b5d924658c8ef0c4148de183bdc42 100644 (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 {